C++-14引入了std::enable_if_t。
它和std::enable_if的区别是什么?使用std::enable_if_t有什么优势或区别吗?
std::enable_if_t是std::enable_if的inner::type的类型别名,它是语法糖,所以你不必写下
typename std::enable_if</* */>::type
std::enable_if_t
使您可以跳过 typename
和 ::type
. 所以... std::enable_if_t
的别称。std::enable_if</* */>::type
.
因此,不要用类型名 std::enable_if</* */>::type
,你可以写成 std::enable_if_t</* */>
.
该 _t
在c++14中引入了别名,即 _v
在c++17中加入了这些。
在任何地方使用 enable_if::type
你可以用 enable_if_t
(只要你的编译器和标准库支持c++14),相反,它们是等价的。
C++14集成了除第4部分以外的所有
由著名的模板元编程大师所写。Walter E. Brown✝.
它之间有什么区别[。
std::enable_if_t
] 和std::enable_if
? 在使用中是否有任何优势或区别?std::enable_if_t
?
该 _t
的别名模板,用于访问底层的 type
的元函数。typename metafunction-name<metafunction-argument(s)>::type
, 并非仅仅是作为句法糖添加到语言中去但也是为了减轻没有经验的人的负担(Brown: "[.]不专业")元编程开发人员在使用元函数时遇到编译器错误信息时的应对措施。引用第2节(大部分内容)。提案)的N3655[重音 我的]。
遗憾的是,上述灵活性对最常见的用例来说是有代价的。在模板上下文中,C++要求对元函数的每个 "元调用 "都要承担语法开销,其形式是一个介绍性的 "元函数"。
typename
关键字,以及后缀的::type
:typename metafunction-name<metafunction-argument(s)>::type
即使是相对简单的构图,也会相当迅速地变得有些混乱;更深的嵌套简直是不堪重负。
template< class T > using reference_t = typename conditional<is_reference<T>::value, T, typename add_lvalue_reference<T>::type>::type;
更糟。如果不小心遗漏了关键字,可能会导致程序员无法理解的诊断结果 不擅长元编程细节的人。
[.]因此,我们 建议增加一组模板别名 为图书馆的 转化特征 为了减轻程序员的负担 [...]. 请注意,在以下对上述例子的改写中: 没有任何
typename
关键字以及 没有任何::type
后缀因此 简述 从3行代码到2行代码。template< class T > using reference_t = conditional_t< is_reference<T>::value, T, add_lvalue_reference_t<T> >;
[......]我们建议将别名改为......。连名带姓即 的别名性状的名称,后缀为
_t
的常规后缀,表示类型别名。因此,例如add_cv<T>::type
将是add_cv_t<T>
.
因此,一般情况下,为了简洁和较小的隐患风险(缺乏 typename
-引起的)编译器错误,从C++14开始,总是倾向于使用别名模板(如 add_cv_t<T>
),而不是更啰嗦的形式(如? typename add_cv<T>::type
).
[...]使用别名模板有什么优势或区别吗?
std::enable_if_t
?
即,对于你的特殊例子,总是倾向于使用别名模板。std::enable_if_t<T>
而不是更冗长的形式 typename enable_if<T>::type
.
注意,从C++17开始。
已被改编,简而言之,对具有单一性状的性状适用类似的模式。static
常量成员 value
,提供一个后缀为 _v
. 援引P0006R0的摘要说明: P0636R0 (C++14和C++17之间的变化)
对于每个标准类型特征
foo
只有一个静态的成员常数foo<Args...>::value
现在,有一个可变的模板foo_v<Args...>
.
(✝) 关于Walter E. Brown关于模板的一些优秀演讲,请参见例如。