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

问题描述 投票:3回答:1

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

情况实际上非常简单。

带有模板参数T的模板类

2个特定类型的T不应实现的功能。

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

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

任何简单的例子?

或者是否有其他选项(C ++ 11)不使用std::enable_if

c++ c++11 templates sfinae enable-if
1个回答
3
投票

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

假设你想要一个有两个成员的foo<T>类,void foo<T>::bar1 (int)int foo<T>::bar2 (),并假设你想要bar1()bar2()只有在Tlong不同时才能实现。

你可以这样做

#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; }
© www.soinside.com 2019 - 2024. All rights reserved.