带有 lambda 表达式的 constexpr 的 C++ 用法

标签 c++ lambda c++17 constexpr

我在看书C++17 - The Complete Guideconstexpr 的第 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 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 对象和 中的 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/

相关文章:

java - 如何在不同的 lambda 表达式中使用 lambda 表达式中的对象

c++ - 在 lower_bound 上使用 lambda

c++ - Clang LLVM C++ `std::optional<std::optional<int>>` 令人惊讶的比较行为

c++ - 构造 std::tuple 类型的索引数组

c++ - WSARecv Hook : prevent packet from being recieved by the executable

lambda - 为什么我不能在 kotlin 中使用 lambda 接口(interface)?

c++ - 这段代码中关于 n 在 pc[i] 中的表示是怎么回事

c++ - 为什么在 std::optional 的某些实现中存在虚拟 union 成员?

python - 在我的 Mac 上安装 pycrypto 时出错

c++ - 使用 MS 编译器的 std::cout 非常慢