I am basically trying to do the same as std::enable_if : parameter vs template parameter but I can't get my code to compile.
I had a simple first version that has the std::enable_if in the parameters and which works fine:
#include <iostream>
#include <type_traits>
template <typename T>
void foo(T t, typename std::enable_if< std::is_same<T, int>::value >::type* = 0) {
std::cout << "int" << std::endl;
}
template <typename T>
void foo(T t, typename std::enable_if< !std::is_same<T, int>::value >::type* = 0) {
std::cout << "not int" << std::endl;
}
int main(int argc, char* argv[])
{
foo(10);
foo(10.1);
return 0;
}
But I thought it might be more concise if the template stuff was in one place and wanted the enable_if out of the function arguments.
Now if I simply move the enable_if part I get the following:
#pragma warning(1 : 4519)
#include <iostream>
#include <type_traits>
template <typename T, typename std::enable_if< std::is_same<T, int>::value >::type = 0>
void foo(T t) {
std::cout << "int" << std::endl;
}
template <typename T, typename std::enable_if< !std::is_same<T, int>::value >::type = 0>
void foo(T t) {
std::cout << "not int" << std::endl;
}
int main(int argc, char* argv[])
{
foo(10);
foo(10.1);
return 0;
}
The #pragma warning(1 : 4519) I needed because otherwise default arguments on a function template are an error in VS2010. The problem is it still doesn't compile.
The first message was: error C2783: 'void foo(T)' : could not deduce template argument for '__formal'
and even though I don't want to do that I tried explicitly stating which template I want by calling it using
foo<int, int>(10);
foo<double, double>(10.1);
but it still doesn't work and the new error is.
error C2975: 'foo' : invalid template argument for 'unnamed-parameter', expected compile-time constant expression
I hope somebody can tell me how to fix this and of course all comments on my style and other issues my code might have are welcome. :)
Extra question: Does anybody know why VS2010 does not allow default arguments on function templates by default?
The problem is that the second template parameter in std::enable_if
defaults to void
. So your doing something which is pretty much the same as:
template <typename T, void = 0>
Which makes substitution fail always. You could use a non-type template argument of type int
, which you can give a default 0 value:
template <typename T, typename std::enable_if< std::is_same<T, int>::value, int >::type = 0>
Do the same for both overloads, and it will work.
Demo here.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With