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

How to disable a class member function for certain template types

本文关键字:成员 函数 类型 何禁用      更新时间:2023-10-16

这似乎很简单,但我对std::enable_if的语法有一些困难

情况其实很简单。

具有模板参数T的模板类

2 不得针对特定类型的T实现的功能。

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

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

任何简单的例子?

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

这真的很简单。只需记住使用默认为类/结构模板参数的另一个模板参数。

假设您想要一个具有两个成员 void foo<T>::bar1 (int)int foo<T>::bar2 () 的类foo<T>,并假设您希望仅在Tlong 不同时才实现bar1()bar2()

您可以执行以下操作

#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和几个 如果::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; }

截至 C++20,requires 关键字使事情变得更加简单:

   void bar1 (int) requires (!std::is_same_v<T, long>)
       { }
   int bar2 () requires (!std::is_same_v<T, long>)
       { return 0; }