• Create Account

Posted 01 September 2012 - 03:08 PM

EDIT: @sunder. I tried the little test example you gave which also compiled on gcc 4.7.1, however if you change mytype to a class instead of a simple typedef to one of the built in types, the problem I am having arises. here is what g++ had to say about it with code:

first.hpp
#ifndef __HEADER_FIRST_HPP__
#include <type_traits>
template <typename T> typename std::enable_if<std::is_arithmetic<T>::value, int>::type func(const T& x)
{ return x; }


second.hpp
#ifndef __HEADER_SECOND_HPP__
#include "first.hpp"
class mytype { mytype( ) = default; };
template <> typename std::enable_if<true, int>::type func(const mytype& x)
{ return 0; }


main.cpp
#include <iostream>
#include "second.hpp"
int main(int, char**)
{
std::cout << func(1.0) << std::endl;
std::cout << func(mytype( )) << std::endl;
return 0;
}


In file included from main.cpp:2:0:
second.hpp:8:54: error: template-id 'func<mytype>' for 'std::enable_if<true, int>::type func(const mytype&)' does not match any template declaration
main.cpp: In function 'int main(int, char**)':
main.cpp:7:29: error: no matching function for call to 'func(mytype)'
main.cpp:7:29: note: candidate is:
In file included from second.hpp:4:0,
from main.cpp:2:
first.hpp:6:88: note: template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&)
first.hpp:6:88: note: template argument deduction/substitution failed:
first.hpp: In substitution of 'template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&) [with T = mytype]':
main.cpp:7:29: required from here
first.hpp:6:88: error: no type named 'type' in 'struct std::enable_if<false, int>'

This code compiles in GCC 4.6. I don't have 4.7 to test with.

#include <type_traits>
// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return x; }
// something.hpp
typedef int mytype;
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept { return 0; }
int main() {
func(0.0);
func(0);
}


I actually had the implementation of the specialization in a seperate .cpp file, perhaps this is my error. I'll give it a go

You could try changing the specialization to:

template <> typename std::enable_if<std::is_arithmetic<mytype>::value, mytype>::type func(const mytype& x) noexcept;


I could try this but it would involve specializing is_arithmetic for mytype which is something I don't really want to do. Even still it would only evaluate to true and produce the same problems.

If that doesn't work, you might not need a function specialization in the first place (I'm not sure what exactly you're trying to do), so you ought to be able to use function overloading:

mytype func(const mytype& x) noexcept;


Yeah, it occurred to me that the specialization may not be necessary in the first place and I could have just created an overload (which is what I have done and it seems to work). I think I was concerned that creating an overload would break func for integer types because mytype does not have an explicit constructor and it still takes a single argument integer value. However this is not the case apparently.

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?

Yes. You can't have a partial function specialization in C++ so all function specializations must start with "template<>" (as far as I know).

I'm pretty sure partial specializations are allowed for functions, what I had done was not a partial specialization.

I think I would be more comfortable with a template specialization in the header than an overload because of the potential problem I spoke about above. Lets see if it works

Posted 01 September 2012 - 03:07 PM

EDIT: @sunder. I tried the little test example you gave which also compiled on gcc 4.7.1, however if you change mytype to a class instead of a simple typedef to one of the built in types, the problem I am having arises. here is what g++ had to say about it with code:

first.hpp
#ifndef __HEADER_FIRST_HPP__
#include <type_traits>
template <typename T> typename std::enable_if<std::is_arithmetic<T>::value, int>::type func(const T& x)
{ return x; }


second.hpp
#ifndef __HEADER_SECOND_HPP__
#include "first.hpp"
class mytype { mytype( ) = default; };
template <> typename std::enable_if<true, int>::type func<mytype>(const mytype& x)
{ return 0; }


main.cpp
#include <iostream>
#include "second.hpp"
int main(int, char**)
{
std::cout << func(1.0) << std::endl;
std::cout << func(mytype( )) << std::endl;
return 0;
}


In file included from main.cpp:2:0:
second.hpp:8:54: error: template-id 'func<mytype>' for 'std::enable_if<true, int>::type func(const mytype&)' does not match any template declaration
main.cpp: In function 'int main(int, char**)':
main.cpp:7:29: error: no matching function for call to 'func(mytype)'
main.cpp:7:29: note: candidate is:
In file included from second.hpp:4:0,
from main.cpp:2:
first.hpp:6:88: note: template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&)
first.hpp:6:88: note: template argument deduction/substitution failed:
first.hpp: In substitution of 'template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&) [with T = mytype]':
main.cpp:7:29: required from here
first.hpp:6:88: error: no type named 'type' in 'struct std::enable_if<false, int>'

This code compiles in GCC 4.6. I don't have 4.7 to test with.

#include <type_traits>
// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return x; }
// something.hpp
typedef int mytype;
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept { return 0; }
int main() {
func(0.0);
func(0);
}


I actually had the implementation of the specialization in a seperate .cpp file, perhaps this is my error. I'll give it a go

You could try changing the specialization to:

template <> typename std::enable_if<std::is_arithmetic<mytype>::value, mytype>::type func(const mytype& x) noexcept;


I could try this but it would involve specializing is_arithmetic for mytype which is something I don't really want to do. Even still it would only evaluate to true and produce the same problems.

If that doesn't work, you might not need a function specialization in the first place (I'm not sure what exactly you're trying to do), so you ought to be able to use function overloading:

mytype func(const mytype& x) noexcept;


Yeah, it occurred to me that the specialization may not be necessary in the first place and I could have just created an overload (which is what I have done and it seems to work). I think I was concerned that creating an overload would break func for integer types because mytype does not have an explicit constructor and it still takes a single argument integer value. However this is not the case apparently.

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?

Yes. You can't have a partial function specialization in C++ so all function specializations must start with "template<>" (as far as I know).

I'm pretty sure partial specializations are allowed for functions, what I had done was not a partial specialization.

I think I would be more comfortable with a template specialization in the header than an overload because of the potential problem I spoke about above. Lets see if it works

Posted 01 September 2012 - 03:07 PM

EDIT: @sunder. I tried the little test example you game which also compiled on gcc 4.7.1, however if you change mytype to a class instead of a simple typedef to one of the built in types, the problem I am having arises. here is what g++ had to say about it with code:

first.hpp
#ifndef __HEADER_FIRST_HPP__
#include <type_traits>
template <typename T> typename std::enable_if<std::is_arithmetic<T>::value, int>::type func(const T& x)
{ return x; }


second.hpp
#ifndef __HEADER_SECOND_HPP__
#include "first.hpp"
class mytype { mytype( ) = default; };
template <> typename std::enable_if<true, int>::type func<mytype>(const mytype& x)
{ return 0; }


main.cpp
#include <iostream>
#include "second.hpp"
int main(int, char**)
{
std::cout << func(1.0) << std::endl;
std::cout << func(mytype( )) << std::endl;
return 0;
}


In file included from main.cpp:2:0:
second.hpp:8:54: error: template-id 'func<mytype>' for 'std::enable_if<true, int>::type func(const mytype&)' does not match any template declaration
main.cpp: In function 'int main(int, char**)':
main.cpp:7:29: error: no matching function for call to 'func(mytype)'
main.cpp:7:29: note: candidate is:
In file included from second.hpp:4:0,
from main.cpp:2:
first.hpp:6:88: note: template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&)
first.hpp:6:88: note: template argument deduction/substitution failed:
first.hpp: In substitution of 'template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&) [with T = mytype]':
main.cpp:7:29: required from here
first.hpp:6:88: error: no type named 'type' in 'struct std::enable_if<false, int>'

This code compiles in GCC 4.6. I don't have 4.7 to test with.

#include <type_traits>
// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return x; }
// something.hpp
typedef int mytype;
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept { return 0; }
int main() {
func(0.0);
func(0);
}


I actually had the implementation of the specialization in a seperate .cpp file, perhaps this is my error. I'll give it a go

You could try changing the specialization to:

template <> typename std::enable_if<std::is_arithmetic<mytype>::value, mytype>::type func(const mytype& x) noexcept;


I could try this but it would involve specializing is_arithmetic for mytype which is something I don't really want to do. Even still it would only evaluate to true and produce the same problems.

If that doesn't work, you might not need a function specialization in the first place (I'm not sure what exactly you're trying to do), so you ought to be able to use function overloading:

mytype func(const mytype& x) noexcept;


Yeah, it occurred to me that the specialization may not be necessary in the first place and I could have just created an overload (which is what I have done and it seems to work). I think I was concerned that creating an overload would break func for integer types because mytype does not have an explicit constructor and it still takes a single argument integer value. However this is not the case apparently.

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?

Yes. You can't have a partial function specialization in C++ so all function specializations must start with "template<>" (as far as I know).

I'm pretty sure partial specializations are allowed for functions, what I had done was not a partial specialization.

I think I would be more comfortable with a template specialization in the header than an overload because of the potential problem I spoke about above. Lets see if it works

Posted 01 September 2012 - 03:04 PM

EDIT: @sunder. I tried the little test example you game which also compiled on gcc 4.7.1, however if you change mytype to a class instead of a simple typedef to one of the built in types, the problem I am having arises. here is what g++ had to say about it with code:

first.hpp
#ifndef __HEADER_FIRST_HPP__
#include <type_traits>
template <typename T> typename std::enable_if<std::is_arithmetic<T>::value, int>::type func(const T& x)
{ return x; }


second.hpp
#ifndef __HEADER_SECOND_HPP__
#include "first.hpp"
class mytype { mytype( ) = default; };
template <> typename std::enable_if<true, int>::type func<mytype>(const mytype& x)
{ return 0; }


main.cpp
#include <iostream>
#include "second.hpp"
int main(int, char**)
{
std::cout << func(1.0) << std::endl;
std::cout << func(mytype( )) << std::endl;
return 0;
}


In file included from main.cpp:2:0:
second.hpp:8:54: error: template-id 'func<mytype>' for 'std::enable_if<true, int>::type func(const mytype&)' does not match any template declaration
main.cpp: In function 'int main(int, char**)':
main.cpp:7:29: error: no matching function for call to 'func(mytype)'
main.cpp:7:29: note: candidate is:
In file included from second.hpp:4:0,
from main.cpp:2:
first.hpp:6:88: note: template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&)
first.hpp:6:88: note: template argument deduction/substitution failed:
first.hpp: In substitution of 'template<class T> typename std::enable_if<std::is_arithmetic<_Tp>::value, int>::type func(const T&) [with T = mytype]':
main.cpp:7:29: required from here
first.hpp:6:88: error: no type named 'type' in 'struct std::enable_if<false, int>'

This code compiles in GCC 4.6. I don't have 4.7 to test with.

#include <type_traits>
// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return x; }
// something.hpp
typedef int mytype;
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept { return 0; }
int main() {
func(0.0);
func(0);
}


I actually had the implementation of the specialization in a seperate .cpp file, perhaps this is my error. I'll give it a go

You could try changing the specialization to:

template <> typename std::enable_if<std::is_arithmetic<mytype>::value, mytype>::type func(const mytype& x) noexcept;


I could try this but it would involve specializing is_arithmetic for mytype which is something I don't really want to do. Even still it would only evaluate to true and produce the same problems.

If that doesn't work, you might not need a function specialization in the first place (I'm not sure what exactly you're trying to do), so you ought to be able to use function overloading:

mytype func(const mytype& x) noexcept;


Yeah, it occurred to me that the specialization may not be necessary in the first place and I could have just created an overload (which is what I have done and it seems to work). I think I was concerned that creating an overload would break func for integer types because mytype does not have an explicit constructor and it still takes a single argument integer value. However this is not the case apparently.

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?

Yes. You can't have a partial function specialization in C++ so all function specializations must start with "template<>" (as far as I know).

I'm pretty sure partial specializations are allowed for functions, what I had done was not a partial specialization.

I think I would be more comfortable with a template specialization in the header than an overload because of the potential problem I spoke about above. Lets see if it works

Posted 01 September 2012 - 02:11 PM

This code compiles in GCC 4.6. I don't have 4.7 to test with.

#include <type_traits>
// firstsomething.hpp
template <typename T>
typename std::enable_if<std::is_arithmetic<T>::value, T>::type func(const T& x) noexcept
{ return x; }
// something.hpp
typedef int mytype;
template <> typename std::enable_if<true, mytype>::type func(const mytype& x) noexcept { return 0; }
int main() {
func(0.0);
func(0);
}


I actually had the implementation of the specialization in a seperate .cpp file, perhaps this is my error. I'll give it a go

You could try changing the specialization to:

template <> typename std::enable_if<std::is_arithmetic<mytype>::value, mytype>::type func(const mytype& x) noexcept;


I could try this but it would involve specializing is_arithmetic for mytype which is something I don't really want to do. Even still it would only evaluate to true and produce the same problems.

If that doesn't work, you might not need a function specialization in the first place (I'm not sure what exactly you're trying to do), so you ought to be able to use function overloading:

mytype func(const mytype& x) noexcept;


Yeah, it occurred to me that the specialization may not be necessary in the first place and I could have just created an overload (which is what I have done and it seems to work). I think I was concerned that creating an overload would break func for integer types because mytype does not have an explicit constructor and it still takes a single argument integer value. However this is not the case apparently.

I did add 'template <typename T>' to the specializations instead of 'template <>' but doesn't this then mean the functions are no longer specializations of the original?

Yes. You can't have a partial function specialization in C++ so all function specializations must start with "template<>" (as far as I know).

I'm pretty sure partial specializations are allowed for functions, what I had done was not a partial specialization.

I think I would be more comfortable with a template specialization in the header than an overload because of the potential problem I spoke about above. Lets see if it works

PARTNERS