使用 std::is_same 进行元编程

使用 std::is_same 进行元编程

问题描述:

是否可以在没有模板专业化的情况下执行类似以下的编译?

Is it possible to do something like the following that compiles without template specialization?

template <class T> 
class A {
public:
  #if std::is_same<T,int>
  void has_int() {}
  #elif std::is_same<T,char>
  void has_char() {}
  #endif
};
A<int> a; a.has_int();
A<char> b; b.has_char();

是的.制作函数模板,然后使用 std::enable_if 有条件地启用它们:

Yes. Make the function templates and then conditionaly enable them using std::enable_if:

#include <type_traits>

template <class T> 
class A {
public:

  template<typename U = T>
  typename std::enable_if<std::is_same<U,int>::value>::type
  has_int() {}

  template<typename U = T>
  typename std::enable_if<std::is_same<U,char>::value>::type
  has_char() {}
};

int main()
{
    A<int> a;
    a.has_int();   // OK
    // a.has_char();  // error
}

来自另一个答案的解决方案可能不可行,如果类很大并且有许多需要不管 T.但是您可以通过从仅用于这些特殊方法的另一个类继承来解决此问题.然后,您可以只专门化该基类.

The solution from the other answer might not be feasible if the class is big and has got many functions that need to regardless of T. But you can solve this by inheriting from another class that is used only for these special methods. Then, you can specialize that base class only.

在 C++14 中,有方便的类型别名,所以语法可以变成:

In C++14, there are convenient type aliases so the syntax can become:

std::enable_if_t<std::is_same<U, int>::value>

还有 C++17,甚至更短:

And C++17, even shorter:

std::enable_if_t<std::is_same_v<U, int>>