我正在阅读《C ++ 17-完整指南》,在关于constexpr
lambda的6.1节中,作者提供了两个示例:
auto squared1 = [](auto val) constexpr { // example 1. compile-time lambda calls
return val * val;
};
和
constexpr auto squared2 = [](auto val) { // example 2. compile-time initialization
return val * val;
};
并且说这两者在示例1在编译时进行评估和示例2在编译时进行初始化的意义上彼此不同。
然后作者发表以下我不完全理解的陈述:
如果(仅)lambda是
constexpr
它,则可以在编译时使用,但是如果由lambda初始化的(closure)对象为constexpr
,则在程序启动时初始化该对象,但是lambda可能仍然是只能在以下位置使用的lambda运行时间(例如,使用静态变量)。因此,您可以考虑声明:constexpr auto squared = [](auto val) constexpr { // example 3 return val * val; };
上面的陈述到底是什么意思?
显然,在示例3中,constexpr
关键字出现在squared2
lambda对象的初始化语句上以及lambda表达式本身上,但是与示例1相比,我不明白该关键字的优点是什么。
事实是,一个auto
声明的对象不采用constexpr
其初始化表达式的本质,而仅采用其类型。并且constexpr
是不该类型的一部分。看到:
为什么`auto`不采用其初始化表达式的constexpr'性?
因此,假设我有:
auto five_squared = 25;
值25非常大constexpr
,即可以在编译时使用。但是-在编译时five_squared
将不可用。您仍然需要指出它是constexpr
(*)。
Lambda基本上相同。Lambda是带有的现场定义类的实例operator()
。如果您自己不做任何事情,那将不会squared
成为constexpr
变量。
(*)-请注意,由于C ++语言中的特殊规则,const
使用常量表达式初始化的整数是自动生成的constexpr
,因此您可以编写const auto
并constexpr
隐式获取。但是,这是一个必须记住的棘手的特殊情况,因此,如果要创建一个变量,constexpr
我建议对其进行明确化。感谢@cigien提出这一点。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句