问题
As an experiment, I am trying to make a void member function with no parameters change behavior based on the class template parameter:
#include <iostream>
#include <limits>
template<typename T>
class MyClass
{
public:
void MyFunc(const typename std::enable_if<std::is_fundamental<T>::value, T> dummy = T());
void MyFunc(const typename std::enable_if<!std::is_fundamental<T>::value, T> dummy = T());
};
template<typename T>
void MyClass<T>::MyFunc(const typename std::enable_if<std::is_fundamental<T>::value, T> dummy)
{
}
template<typename T>
void MyClass<T>::MyFunc(const typename std::enable_if<!std::is_fundamental<T>::value, T> dummy)
{
}
class Simple {};
int main(int argc, char *argv[])
{
MyClass<int> myClass;
myClass.MyFunc();
// MyClass<Simple> myClass2;
// myClass2.MyFunc();
return 0;
}
However, I am getting: error: call of overloaded ‘MyFunc()’ is ambiguous. Shouldn't only one or the other of those functions get defined, since everything is the same except for a ! in one of them?
回答1:
No, first you need to actually access the ::type
typedef of enable_if
, and second, your code will not work because your members are not templates. One of them always will end up being an invalid declaration.
After applying the necessary ::type
fix, your code will fail when instantiating MyClass<int>
, long before you try to call the member.
Make your members member templates, and make the enable_if
depend on a parameter of the member template, instead of on a parameter of the enclosing class template.
回答2:
You have to make dummy template parameters to do what I was asking:
#include <iostream>
#include <limits>
template<typename T>
class MyClass
{
public:
template <typename U = T>
void MyFunc(const typename std::enable_if<std::is_fundamental<U>::value, U>::type dummy = U());
template <typename U = T>
void MyFunc(const typename std::enable_if<!std::is_fundamental<U>::value, U>::type dummy = U());
};
template<typename T>
template<typename U>
void MyClass<T>::MyFunc(const typename std::enable_if<std::is_fundamental<U>::value, U>::type dummy)
{
}
template<typename T>
template<typename U>
void MyClass<T>::MyFunc(const typename std::enable_if<!std::is_fundamental<U>::value, U>::type dummy)
{
}
class Simple {};
int main(int argc, char *argv[])
{
MyClass<int> myClass;
myClass.MyFunc();
MyClass<Simple> myClass2;
myClass2.MyFunc();
return 0;
}
回答3:
Say:
std::enable_if<std::is_fundamental<T>::value, T>::type
// ^^^^^^
来源:https://stackoverflow.com/questions/8735812/enable-if-function-defined-when-it-shouldnt-be