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

Wal*_*orf 6 c++ templates sfinae enable-if c++11

看起来很简单,但我在语法上有一些困难 std::enable_if

情况其实很简单。

带有模板参数的模板类 T

2 不得为一种特定类型的T.

这两个函数都没有参数或返回值 T

一个函数接受一个int,另一个函数返回一个int

有什么简单的例子吗?

还是有另一个不使用的选项(C++11)std::enable_if

max*_*x66 7

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

假设你想要一个foo<T>有两个成员的类,void foo<T>::bar1 (int)并且int foo<T>::bar2 ()假设你想要那个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
 }
Run Code Online (Sandbox Code Playgroud)

有一个危险:有人可以绕过你的控制并显式U类型如下

foo<long> fl;

fl.bar1<long long>(0);
Run Code Online (Sandbox Code Playgroud)

为了避免这个问题,你可以改进你的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; }
Run Code Online (Sandbox Code Playgroud)

如果你可以使用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; }
Run Code Online (Sandbox Code Playgroud)

  • 谢谢它完美地做到了我想要的。但我仍然缺乏一些了解。为什么不能直接使用 'T' 而不是 'U' ;&lt;类型名 U = T&gt; ? 还有第二个例子 sizeof(U) 这怎么会导致 0 ? (2认同)