std::enable_if 和 std::enable_if_t 有什么区别?
What is the difference between std::enable_if and std::enable_if_t?
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
的别名。
所以代替类型名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
有什么优点或区别吗?
用于访问元函数底层type
typename 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...>::value
foo
的标准类型特征,现在有一个变量模板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"。
- 使用std::multimap迭代器创建std::list
- C++中std::resize(n)和std::shrink_to_fit之间的区别
- 来自 std::list 的迭代器 .end() 按预期返回"0xcdcdcdcdcdcdcdcd"但 .begin()
- C++17复制构造函数,在std::unordereded_map上进行深度复制
- 如何导出包含具有"std::unique_ptr"值的"std::map"属性的
- 从持续时间构造std::chrono::system_clock::time_point
- std::具有相同基类的类的变体
- std::向量与传递值的动态数组
- 使用std::vector的OpenCL矩阵乘法
- std::map<struct,struct>::find 找不到匹配项,但是如果我循环通过 begin() 到 end(),我在那里看到匹配项
- std::condition_variable::wait()如何评估给定的谓词
- 如何获取std::result_of函数的返回类型
- std::原子加载和存储都需要吗
- 将对象移动到std::shared_ptr
- POCO::PostgreSQL:如何将std::vector支持添加到`Binder::bind`
- 使用一个考虑到std::map中键值的滚动或换行的键
- 如何从 std::atomic 中提取指针 T<T>?
- 为什么 std::unique 不调用 std::sort?
- 使用std::函数映射对象方法
- Linux gnu++11,在运行时获取"Enable multithreading to use std::thread: Operation not permitted"