首页 文章

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

提问于
浏览
2

根据enable_if结构的定义:

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 回答

  • 2

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

    我想知道如何在没有指定类型T的情况下调用

    • 它不会;仅当用户需要使用 T 的特定值进行实例化(隐式或显式)时,才会实例化 fooenable_if 模板 . 所以始终指定 T .

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

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

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

    将只是 int f() .

  • 1

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

    事实上,再想一想:在推断 foo(1.0) 的参数时,第一个版本(你写的那个)实际上是错误的,因为没有成员类型 ::type . 但是,这不是一个硬编译器错误,而只是一个所谓的"substitution failure" - 这不是错误 . 它只是从考虑中删除整个模板 .

    作为旁注,在类模板中有 enable_if 的相关用法,以帮助消除特化的歧义,同样使用默认参数 . 它看起来像 template <typename T, typename = typename std::enable_if<some_condition>::type> ...

相关问题