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

11

C++17版本中,std::addressof的规范已更改:现在它可以是一个常量表达式。然而,cppreference说:

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

  • 什么是常量子表达式?
  • 举个例子,什么情况下 std::addressof(E) 将是一个常量表达式?
  • 举个例子,什么情况下 std::addressof(E) 不会是一个常量表达式?
答案: - 常量子表达式指的是在编译时就可以确定结果的表达式,例如字面值、constexpr变量、枚举等。 - 当E是一个constexpr变量或者字面值时,std::addressof(E)将是一个常量表达式。 - 当E是一个非constexpr变量时,std::addressof(E)将不会是一个常量表达式。
1个回答

12

这在这里有解释。

在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

}

我说的不是一个常量表达式。 - M.M
@M.M 我修改了示例,希望现在更清晰了。 - Brian Bi
在C++14中,x(自动变量)是一个常量表达式;因此,核心常量表达式的定义是否也已更改,将某些常量表达式降级为子表达式? - M.M
据我所知,@M.M并没有错...该措辞被认为是相对于N3936的,并且据我所知,N3936与N4141具有相同的“常量表达式”定义。 - Brian Bi
好的。我重新阅读了C++14的定义。我认为问题在于x(第二个)是一个核心常量表达式(和一个转换常量表达式),但不是一个常量表达式。所以,回到OP的第一个问题:你已经给出了常量子表达式的定义,但是对我来说仍然不清楚其含义。所有核心常量表达式也都是常量子表达式吗?有没有任何常量子表达式不是核心常量表达式 - M.M
显示剩余4条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接