enable_if结构定义和默认模板参数

时间:2012-11-13 13:29:03

标签: c++ templates

根据enable_if struct的定义:

template<bool B, class T = void>
struct enable_if {};

template<class T>
struct enable_if<true, T> { typedef T type; };

我想知道如何

template<class T>
T foo(T t, typename std::enable_if<std::is_integral<T>::value >::type* = 0) 
{
    return t;
}

特别是:

typename std::enable_if<std::is_integral<T>::value >::type
如果std::is_integral<T>::value等于true,则可以在没有指定类型T的情况下调用

。在这种情况下,将调用std :: enable_if的特化,在此定义中没有默认模板参数。

是否由于推导出模板参数机制?如果是,为什么为非专业化定义指定了默认参数?

2 个答案:

答案 0 :(得分:2)

你的问题有点神秘,但据我所知:

  

我想知道如何在没有指定类型T

的情况下调用...
  1. 不会;仅当用户需要使用foo 的特定值进行实例化(隐式或显式)时,才会实例化enable_ifT模板。因此始终指定T

  2. 默认模板参数仅在“基本”模板定义上有特色(即不是特化)。这就是为什么你只在enable_if的第一个声明中看到它。但是,它们会影响所有特化(基本上,如果您实例化enable_if<X>,编译器会发现您没有为基本模板提供其中一个参数,并尝试将所有特化与参数列表<X, void>匹配。 / p>

  3. BTW第二个模板参数用于从enable_if中获取与void不同的类型:

    std:enable_if<1, int>::type f();
    

    只是int f()

答案 1 :(得分:1)

enable_if模板的目的是从重载集中删除函数模板。就其本身而言,您的示例并不十分有用,只是它会拒绝对具有编译器错误的非整数类型进行实例化。但是如果你还写了第二个重载,例如反向条件,那么foo(1)foo(1.0)都只能找到一个可行的重载,并且没有歧义。

事实上,再想一想:在推断foo(1.0)的参数时,第一个版本(你写的那个)实际上是错误的,因为没有成员类型::type。但是,这是硬编译器错误,而只是所谓的“替换失败” - 而错误。它只是考虑了整个模板。

作为旁注, class 模板中enable_if的相关用途有助于消除歧义特化,也使用默认参数。它看起来像template <typename T, typename = typename std::enable_if<some_condition>::type> ...