std::enable_if 和 std::enable_if_t 有什么区别?

What is the difference between std::enable_if and std::enable_if_t?

本文关键字:std enable if 区别 什么      更新时间:2023-10-16

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_tstd::enable_if</* */>::type的别名。

所以代替类型名std::enable_if</* */>::type,你可以写成std::enable_if_t</* */>

C++14 (N3655(:特征的别名模板

C++14 集成了除第 4 部分之外的所有

内容
  • N3655:转换特征 Redux,v2

由著名的模板元编程大师Walter E. Brown撰写。

它[std::enable_if_t]和std::enable_if有什么区别?使用std::enable_if_t有什么优点或区别吗?

用于访问元函数底层typetypename metafunction-name<metafunction-argument(s)>::type_t别名模板不仅作为语法糖添加到语言中,而且还减轻了没有经验的负担(Brown:">[...]inexpert">(元编程开发人员在使用元函数时遇到编译器错误消息时。引用 N2 第 3655 节(提案(的大部分内容 [强调我的]:

不幸的是,上述灵活性伴随着 最常见的用例。在模板上下文中,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 (P0006R0(: 特征的变量模板

请注意,截至 C++17,

  • P0006R0:采用库基础 TS 中的类型特征变量模板 C++17

已经改编,简而言之,对具有名为value的单个static成员常量的特征应用了类似的模式,提供了一个后缀为_v的变量模板助手。引用P0636R0 P0006R0摘要/注释(C++14 和 C++17 DIS 之间的变化(

对于每个具有单个静态成员常量foo<Args...>::valuefoo的标准类型特征,现在有一个变量模板foo_v<Args...>


(✝(有关 Walter E. Brown 关于模板的一些精彩演讲,请参阅例如:

  • CppCon 2018:Walter E. Brown"C++功能模板:它们如何真正工作?
  • CppCon 2014:Walter E. Brown "Modern Template Metaprogramming: A Compendium, Part I",
  • CppCon 2014:Walter E. Brown "Modern Template Metaprogramming: A Compendium, Part II"。