constexpr 与 lambda 表达式的 C++ 用法
C++ usage of constexpr with lambda expression
我正在阅读书 C++17 - The Complete Guide,在第 6.1 节 constexpr
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;
};
并且说这两个在某种意义上是不同的 example 1 在编译时评估并且 示例2在编译时初始化。
然后作者发表了以下我不完全理解的陈述:
If (only) the lambda is constexpr
it can be used at compile time, but
If the (closure) object initialized by the lambda is constexpr
, 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对象的初始化语句和示例3[=41中的lambda表达式本身=] 但我不明白这个比 示例 1 有什么优势。
事实是,一个 auto
声明的对象不采用其初始化表达式的 constexpr
'ness,仅采用其类型; constexpr
是该类型的 而不是 的一部分。参见:
所以,假设我有:
auto five_squared = 25;
值25非常constexpr
,即可以在compile-time处使用。然而 - five_squared
将 不能 在 compile-time 上使用。您仍然需要指明它是 constexpr
(*).
这与您的 lambda 基本相同。 lambda 是 on-the-spot-defined class 和 operator()
的实例。如果您不自己创建一个变量,那么 squared
不会成为一个 constexpr
变量。
(*) - 请注意,由于 C++ 语言中的特殊规则,使用 constant-expression 初始化的 const
整数自动为 constexpr
,所以你 可以 只写 const auto
并隐含地得到 constexpr
。然而,这是一个需要记住的棘手 special-case,所以如果你想创建一个变量 constexpr
,我建议明确说明。感谢@cigien 提出这一点。
我正在阅读书 C++17 - The Complete Guide,在第 6.1 节 constexpr
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;
};
并且说这两个在某种意义上是不同的 example 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对象的初始化语句和示例3[=41中的lambda表达式本身=] 但我不明白这个比 示例 1 有什么优势。
事实是,一个 auto
声明的对象不采用其初始化表达式的 constexpr
'ness,仅采用其类型; constexpr
是该类型的 而不是 的一部分。参见:
所以,假设我有:
auto five_squared = 25;
值25非常constexpr
,即可以在compile-time处使用。然而 - five_squared
将 不能 在 compile-time 上使用。您仍然需要指明它是 constexpr
(*).
这与您的 lambda 基本相同。 lambda 是 on-the-spot-defined class 和 operator()
的实例。如果您不自己创建一个变量,那么 squared
不会成为一个 constexpr
变量。
(*) - 请注意,由于 C++ 语言中的特殊规则,使用 constant-expression 初始化的 const
整数自动为 constexpr
,所以你 可以 只写 const auto
并隐含地得到 constexpr
。然而,这是一个需要记住的棘手 special-case,所以如果你想创建一个变量 constexpr
,我建议明确说明。感谢@cigien 提出这一点。