我在看书C++17 - The Complete Guide在 constexpr
的第 6.1 节中lambda 作者举了两个例子:
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 在编译时初始化。然后作者做了以下我不完全理解的陈述:
If (only) the lambda is
constexpr
it can be used at compile time, but If the (closure) object initialized by the lambda isconstexpr
, the object is initialized when the program starts but the lambda might still be a lambda that can only be used at run time (e.g., using static variables). Therefore, you might consider declaring:constexpr auto squared = [](auto val) constexpr { // example 3 return val * val; };
上面的说法究竟是什么意思?
很明显
constexpr
关键字出现在 squared2
的初始化语句中lambda 对象和 中的 lambda 表达式本身示例 3 但我不明白这比 有什么优势示例 1 .
最佳答案
问题是,一个 auto
-声明的对象不采用constexpr
' 初始化表达式的完整性,只有它的类型;和 constexpr
不是那种类型的一部分。看:
Why does `auto` not adopt the constexpr'ness of its initializing expression?
所以,假设我有:
auto five_squared = 25;
值 25 非常多 constexpr
,即它可以在编译时使用。然而 - five_squared
在编译时将不可用。您仍然需要指明它是 constexpr
(*)。它与您的 lambda 基本相同。一个 lambda 是一个现场定义的类的实例,带有
operator()
.没有什么可以使squared
成为 constexpr
如果你不自己做一个变量。(*) - 请注意,由于 C++ 语言中的特殊规则,
const
用常量表达式初始化的整数自动 constexpr
,所以你可以写 const auto
并获得 constexpr
含蓄地。然而,这是一个需要记住的棘手的特殊情况,所以如果你想创建一个变量 constexpr
我建议明确说明它。感谢@cigien 提出这一点。
关于带有 lambda 表达式的 constexpr 的 C++ 用法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/64713512/