Jump to content

  • Log In with Google      Sign In   
  • Create Account

Awesome job so far everyone! Please give us your feedback on how our article efforts are going. We still need more finished articles for our May contest theme: Remake the Classics

#Actualroadysix

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__
#define __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; }
#endif //__HEADER_FIRST_HPP__

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

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 Posted Image

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 Image

#4roadysix

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__
#define __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; }
#endif //__HEADER_FIRST_HPP__

second.hpp
#ifndef __HEADER_SECOND_HPP__
#define __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; }
#endif //__HEADER_SECOND_HPP__

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 Posted Image

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 Image

#3roadysix

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__
#define __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; }
#endif //__HEADER_FIRST_HPP__

second.hpp
#ifndef __HEADER_SECOND_HPP__
#define __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; }
#endif //__HEADER_SECOND_HPP__

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 Posted Image

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 Image

#2roadysix

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__
#define __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; }
#endif //__HEADER_FIRST_HPP__

second.hpp
#ifndef __HEADER_SECOND_HPP__
#define __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; }
#endif //__HEADER_SECOND_HPP__


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 Posted Image

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 Image

#1roadysix

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