std :: enable_if的第二个参数有什么用?

时间:2013-09-24 09:32:03

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

我对std :: enable_if的第二个参数感到困惑。 在使用返回类型的int时,我们可以使用:

template <class T>
typename std::enable_if<mpi::is_builtin<T>::value, int>::type
foo() { return 1; }

但是如何在参数或模板中使用enable_if?在这种情况下,下面的功能有什么不同:

template<class T , 
       class = typename std::enable_if<std::is_integral<T>::value>::type >
T too(T t) { std::cout << "here" << std::endl; return t; }

int too(int t) { std::cout << "there" << std::endl; return t; }

感谢。

2 个答案:

答案 0 :(得分:3)

这意味着在

的情况下
template<class T , 
   class = typename std::enable_if<std::is_integral<T>::value>::type >

它变成了

template<class T , 
   class = void >

如果条件std::is_integral<T>::valuetrue,则因此类型T允许该函数,因此参与重载解析。

如果不满足条件,则它变为非法,typename std::enable_if<...>::type使类型T的函数无效。在您的示例中,第一种方法允许所有整数类型(intunsignedlong,...)但没有类等。

示例中的第二个int - 仅版本会丢失一些信息并将值从unsigned转换为signed或者缩小某些值,这就是为什么第一个版本在某些情况下真的很有用。

请注意,void实际上是std::enable_if的第二个参数的默认值,这通常足以启用或禁用模板等,因为您实际上并不需要特定类型。您需要知道/检测的是,它是否有效(void)或无效,在这种情况下,::type部分没有有效替代。

答案 1 :(得分:0)

  

下面的功能有什么不同:

一个是可以为任何CopyConstructible类型调用的模板,enable_if仅在使用默认模板参数时对其进行约束:

#include <iostream>

template<class T , 
       class = typename std::enable_if<std::is_integral<T>::value>::type >
T too(T t) { std::cout << "here" << std::endl; return t; }

int too(int t) { std::cout << "there" << std::endl; return t; }

int main()
{
    too<double, void>(1.0);
}