【问题标题】:How to disable a class member function for certain template types如何禁用某些模板类型的类成员函数
【发布时间】:2017-03-27 16:36:45
【问题描述】:

看起来很简单,但是我对std::enable_if的语法有些困难

情况其实很简单。

带有模板参数T的模板类

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

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

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

有什么简单的例子吗?

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

【问题讨论】:

    标签: c++ c++11 templates sfinae enable-if


    【解决方案1】:

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

    假设您想要一个具有两个成员 void foo<T>::bar1 (int)int foo<T>::bar2 () 的类 foo<T>,并假设您希望仅当 T 不同于 long 时才实现 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 和一对 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; }
    

    【讨论】:

    • 感谢它完美地满足了我的要求。但我还是缺乏一些了解。为什么不能直接使用 'T' 而不是 'U' ; ?还有第二个例子 sizeof(U) 这怎么会导致 0 ?
    • 不太明白包含 sizeof(U) 有什么帮助
    • ideone 上的示例代码,如果有人想尝试。 1. 没有 sizeof(U) 检查 - ideone.com/k9cvnC 2. 有 sizeof(U) 检查 - ideone.com/EoORcv
    • @SahilSingh - 有助于将std::enalble_if 测试转换为依赖于UT 的测试,而不仅仅是T。如果测试仅依赖于T(即类的模板参数,而不是方法的模板参数),则 SFINAE 不起作用。
    猜你喜欢
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-01
    • 1970-01-01
    • 2011-07-06
    相关资源
    最近更新 更多