C++-14引入了std :: enable_if_t
它与std :: enable_if之间有什么区别?使用std :: enable_if_t是否有任何优势或差异?
std::enable_if_t是std::enable_if的内部::type别名,它是一种语法糖,使您不必编写
typename std::enable_if</* */>::type
_t
别名在 c++14 中引入,_v
别名在 c++17 中添加。
在任何使用 enable_if::type
的地方,您都可以使用 enable_if_t
(只要您的编译器和标准库支持 c++14),它们是等效的。
std::enable_if_t
可以让你省略 typename
和 ::type
。因此,std::enable_if_t
是 std::enable_if</* */>::type
的别名。
所以,你可以将 typename std::enable_if</* */>::type
写成 std::enable_if_t</* */>
。
C++14集成了除第4部分以外的所有内容
std::enable_if_t
和std::enable_if
有什么区别?在使用std::enable_if_t
时有什么优势或区别吗?
_t
别名模板用于访问元函数的底层type
,即typename metafunction-name<metafunction-argument(s)>::type
。这不仅仅是为了语法上的简化,而且也是为了减轻经验不足的元编程开发人员在使用元函数时面对编译器错误消息的负担。引用N3655的第2节(提案)的大部分内容,强调如下:
Unfortunately, the above-described flexibility comes with a cost for the most common use cases. In a template context, C++ requires that each “metacall” to a metafunction bear syntactic overhead in the form of an introductory
typename
keyword, as well as the suffixed::type
:typename metafunction-name<metafunction-argument(s)>::type
Even relatively straightforward compositions can rather quickly become somewhat messy; deeper nesting is downright unwieldy:
template< class T > using reference_t = typename conditional<is_reference<T>::value, T, typename add_lvalue_reference<T>::type>::type;
Worse, accidentally omitting the keyword can lead to diagnostics that are arcane to programmers who are inexpert in metaprogramming details.
[...] We therefore propose to add a set of template aliases for the library’s TransformationTraits in order to reduce the programmer burden [...]. Note, in the following rewrite of the above example, the absence of any
typename
keyword, as well as the absence of any::type
suffix, thus condensing the statement from 3 to 2 lines of code:
template< class T > using reference_t = conditional_t< is_reference<T>::value, T, add_lvalue_reference_t<T> >;
[...] we recommend that aliases be named according to a consistent pattern, namely the name of the aliased trait suffixed by
_t
, the conventional suffix denoting a type alias. Thus, for example, the alias foradd_cv<T>::type
would beadd_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
结尾的变量模板助手。引用来自P0636R0(C++14和C++17 DIS之间的更改)的P0006R0的摘要/注释如下:
对于每个具有单个静态成员常量
foo<Args...>::value
的标准类型特征foo
,现在有一个变量模板foo_v<Args...>
。
(✝) 如果想听 Walter E. Brown 关于模板的优秀演讲,请参见以下链接: