问题
Very often I used SFINAE before but I have a very very simple example I can't get to run today.
class X
{
public:
template <typename CHECK, typename = typename std::enable_if< std::is_floating_point<CHECK>::value, void>::type >
void Do()
{
std::cout << "yes" << std::endl;
}
template <typename CHECK, typename = typename std::enable_if< !std::is_floating_point<CHECK>::value, void>::type>
void Do()
{
std::cout<< "no" << std::endl;
}
};
int main()
{
X x;
x.Do<float>();
}
Error:
src/main.cpp:20:18: error: 'template void X::Do()' cannot be overloaded
src/main.cpp:14:18: error: with 'template void X::Do()' void Do()
I want to disable any overload with enable_if but it doesn't work...
Any idea what today I did wrong?
回答1:
The two functions have the same sigature, so you get a redefinition error. Try it with the following instead, which uses default arguments:
#include <type_traits>
#include <iostream>
class X
{
public:
template <typename CHECK, std::enable_if_t< std::is_floating_point<CHECK>::value>* =nullptr >
void Do()
{
std::cout << "yes" << std::endl;
}
template <typename CHECK, std::enable_if_t< !std::is_floating_point<CHECK>::value>* =nullptr>
void Do()
{
std::cout<< "no" << std::endl;
}
};
int main()
{
X x;
x.Do<float>();
}
DEMO
See also the answers here and here.
回答2:
Another syntax which compiles and works is to move the enable_is
as the return type:
class X
{
public:
template <typename CHECK >
typename std::enable_if< std::is_floating_point<CHECK>::value, void>::type Do()
{
std::cout << "yes" << std::endl;
}
template <typename CHECK>
typename std::enable_if< !std::is_floating_point<CHECK>::value, void>::type Do()
{
std::cout << "no" << std::endl;
}
};
int main()
{
X x;
x.Do<float>();
getchar();
}
来源:https://stackoverflow.com/questions/31539075/sfinae-did-not-compile