c++ - 没有变量说明符的模板参数上的 SFINAE(enable_if)

标签 c++

这是代码:

#include <iostream>
#include <type_traits>


template <class T>
typename std::enable_if<std::is_integral<T>::value,bool>::type
  is_odd (T i) {return bool(i%2);}

// 2. the second template argument is only valid if T is an integral type:
template < class T,
           class = typename std::enable_if<std::is_integral<T>::value>::type>
bool is_even (T i) {return !bool(i%2);}


int main() {

  short int i = 1;    // code does not compile if type of i is not integral

  std::cout << std::boolalpha;
  std::cout << "i is odd: " << is_odd(i) << std::endl;
  std::cout << "i is even: " << is_even(i) << std::endl;

  return 0;
}

我正在努力学习 enable_if 的正确用法,我知道如果它被用作返回类型说明符是:编译器将忽略该代码。意思是,该函数不会在二进制文件中。

如果在模板参数中使用它,我会感到有些困惑。根据上面的代码,它说第二个模板参数只有在 T 是整数类型时才有效但是我很困惑第二个参数的目的是什么?

我将其删除并将其更改为:

template < class T>
bool is_even (T i) {return !bool(i%2);}

它仍然可以正常工作。有人可以澄清一下它的真正目的是什么吗?它也没有变量说明符。

或者如果我做了类似的事情,它可能只是作为检查器使用

template < class T,
           class B= typename std::enable_if<std::is_integral<T>::value>::type>

允许我在我的代码上访问 B(可以是 true 或 false)?

最佳答案

您正在将它与整数类型一起使用。它只会在与非整数类型一起使用时失败。以下应该无法编译:

float f;
is_even(f);

请注意,使用 C++14 编译器,您可以 can write :

template <class T,
          class = std::enable_if_t<std::is_integral<T>::value>>

但是,您可能想要使用 static_assert在这里,因为该函数可能对非整数类型没有意义,它会在编译时给出更好的错误消息。

SFINAE 中附加参数的另一种用法是降低对给定函数的偏好。与模板参数较少的模板相比,模板参数较多的模板被选中的可能性较小。

关于c++ - 没有变量说明符的模板参数上的 SFINAE(enable_if),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31126605/

相关文章:

c++ - 我在 C++ 中的方法有问题

c++ - 来自 boost.lambda 或 boost.phoenix 的静态函数

C++ boost::thread operator()() 问题

c++ - ADO Recordset Field Value to C++ vector/array(捕获指针值)

c++ - 将编译的最小 C++ 程序

c++ - 矩阵类的转置方法

c++ - 复制 CTOR 与赋值运算符初始化对象(性能)

c++ - 为什么我不能 const_cast 转换运算符的返回值?

c++ - 如何使用 make_heap 在 C++ 中创建最小堆

c++ - 使用 NUnit 在 VS 2010 中调试 native /托管 C++