constexpr对象有没有办法引用/指向其他非静态constexpr对象?

Jos*_*vin 2 c++ standards metaprogramming constexpr c++14

假设我想在编译时使用某种算法构建图形,然后计算图形中结束的节点数.这似乎是constexpr的理想情况,而不是模板元编程,因为目标是计算产生一个值,而不是真正的类型.我有一些有用的代码,但功能是如此新,我担心编译器是宽松的,我可以解释部分标准说我不能这样做.

#include <iostream>

struct A { int x; constexpr A(int i) noexcept : x{i} {} };
struct B { A& a; constexpr B(A& a) noexcept : a{a} {} };

constexpr int foo() { 
    A a{55};
    B b{a};
    return b.a.x;
}

template<int N>
void output()
{
    std::cout << N << std::endl;
}

int main() {
    // to be absolutely sure compile time eval'd,
    // pass as template arg
    constexpr auto b = foo();
    output<b>();
}
Run Code Online (Sandbox Code Playgroud)

这两个ab实例都是在编译时创建的,它们具有相同的生命周期,所以这应该是"安全的".但这a是一个非静态对象,标准的这一部分似乎说不允许:

如果实体是具有静态存储持续时间的对象,则该实体是常量表达式的允许结果,该对象不是临时对象,或者是其值满足上述约束的临时对象,或者它是函数.

那我可以或不可以吗?海湾合作委员会和铿锵声都很好.

Pot*_*ter 5

是的,你的例子符合要求.

关于C++ 14放松的特殊之处constexpr在于,在常量表达式的求值中的中间结果本身不需要是常量表达式.

return将lvalue-to-rvalue转换应用于b.a.x,因为函数按值返回,并且b.a.x是:

一个非易失性的文字类型glvalue,它引用一个非易失性对象,其生命周期始于评估范围内 e

(N4527§5.20/ 2.7.4)

如果你试图挽救一个(悬挂)引用b.a.x,这将是一个问题.根据你的引用,这不会是"持续表达的允许结果".