std::addressof作为C++17中的常量表达式

std::addressof as a constant expression in C++17

本文关键字:常量 表达式 C++17 addressof 作为 std      更新时间:2023-10-16

std::addressof的规范已针对C++17进行了更改:现在允许它是一个常量表达式。然而,cppreference说:

表达式std::addressof(E)是常量子表达式,如果E是左值常量子表达式。

  • 什么是常量子表达式
  • std::addressof(E)将是一个常数表达式的例子是什么
  • std::addressof(E)将不是常量表达式的示例是什么

这里对此进行了解释。

在17.3中的现有列表中引入以下新定义[定义]:[起草说明:如果在此之前接受LWG 2234问题,应该使用新定义的公认措辞相反--结束起草说明]

**constant subexpression** [defns.const.subexpr]
an expression whose evaluation as a subexpression of a *conditional-expression* *CE* (5.16 [expr.cond]) would not prevent *CE* from being a core constant expression (5.20 [expr.const]).

所以"常量子表达式"大致意思是"可以在常量表达式中使用它"。

std::addressof(E)将是一个常量表达式的例子是什么?

我相信它的目的是在&E调用时给出一个常量表达式(假设&调用运算符的内置地址)。

constexpr int x  = 42; // static storage duration
constexpr int* p1 = &x; // x is an lvalue constant subexpression
constexpr int* p2 = std::addressof(x); // x is an lvalue constant subexpression

std::addressof(E)不是常量表达式的例子是什么?

std::map<int, int> m;
void f() {
    int& r = m[42];
    constexpr int* z1 = &r; // error: r is not a constant subexpression
    constexpr int* z2 = std::addressof(r); // likewise
    constexpr int x = 43; // automatic storage duration
    constexpr const int y1 = *&x;                // ok; x is a constant subexpression
    constexpr const int y2 = *std::addressof(x); // likewise
    constexpr const int* p1 = &x;                // error: p1 points to an automatic object
    constexpr const int* p2 = std::addressof(x); // likewise
}