enable_if function defined when it shouldn't be

风流意气都作罢 提交于 2021-02-04 16:41:09

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!