如何禁用某些模板类型的 class 成员函数

How to disable a class member function for certain template types

看似简单,但是我对std::enable_if

的语法有些吃力

其实情况很简单。

具有模板参数 T

的模板 class

2 个函数不应为一种特定类型的 T 实现。

两个函数都没有参数或 return 值 T

一个函数接受 int,另一个函数 return 接受 int

有什么简单的例子吗?

或者是否有另一个不使用 std::enable_if 的选项 (C++11)?

真的很简单。请记住使用默认为 class/struct 模板参数的另一个模板参数。

假设您想要一个包含两个成员 void foo<T>::bar1 (int)int foo<T>::bar2 () 的 class foo<T>,并假设您想要 bar1()bar2() 仅在 T 不同于 long.

时实施

您可以进行如下操作

#include <type_traits>

template <typename T>
struct foo
 {
   template <typename U = T>
   typename std::enable_if<false == std::is_same<U, long>::value>::type
      bar1 (int)
       { }

   template <typename U = T>
   typename std::enable_if<false == std::is_same<U, long>::value, int>::type
      bar2 ()
       { return 0; }
 };

int main()
 {
   foo<int>  fi;
   foo<long> fl;

   fi.bar1(0); // compile
   fi.bar2();  // compile

   // fl.bar1(0); // compilation error
   // fl.bar2();  // compilation error
 }

存在危险:有人可以绕过您的控制并显式 U 类型如下

foo<long> fl;

fl.bar1<long long>(0);

为避免此问题,您可以按如下方式改进 std::enable_if 测试

   template <typename U = T>
   typename std::enable_if
         <sizeof(U) && (false == std::is_same<T, long>::value)>::type
      bar1 (int)
       { }

   template <typename U = T>
   typename std::enable_if
         <sizeof(U) && (false == std::is_same<T, long>::value), int>::type
      bar2 ()
       { return 0; }

如果你可以使用 C++14 编译器,使用 std::enable_if_t 你可以避免一些 typename 和一些 if ::type 并简化代码如下

   template <typename U = T>
   std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value)>
      bar1 (int)
       { }

   template <typename U = T>
   std::enable_if_t<sizeof(U) && (false == std::is_same<T, long>::value), int>
      bar2 ()
       { return 0; }