C++ 为什么不能使用 constexpr 创建具有 const 引用成员变量的类?

mik*_*.23 6 c++ constexpr

在以下代码中,我尝试存储对另一个类的 const 引用:

struct A {
};

struct B {
    constexpr B(A const & _a) : a(_a) {}
        
    A const &  a;
};

int main() {
    constexpr A s1;
    constexpr B s2{s1};
}
Run Code Online (Sandbox Code Playgroud)

然而,编译器(gcc 11.1)抱怨:

cctest.cpp: In function ‘int main()’:
cctest.cpp:12:22: error: ‘B{s1}’ is not a constant expression
   12 |     constexpr B s2{s1};
      |
Run Code Online (Sandbox Code Playgroud)

我无法弄清楚为什么s1不被视为常量表达式。s1本身是代码中的 constexpr。我知道这可能与引用的生命周期有关,但我无法弄清楚逻辑。在这个例子的代码中,我不想存储 A 的副本,我真的只想要一个引用或(智能)指针。所以:

  1. 为什么s1不是常量表达式?
  2. 处理此问题的最佳实践方法是什么?

非常感谢!

med*_*le1 5

Clang 12.0.0+ 给出了关于这个问题的描述性说明

note: address of non-static constexpr variable 's1' may differ on each invocation of the enclosing function; add 'static' to give it a constant address
Run Code Online (Sandbox Code Playgroud)

所以你需要在static这里添加一个:

struct A {
};

struct B {
    constexpr B(A const & _a) : a(_a) {}
        
    A const &  a;
};

int main() {
    constexpr static A s1;
    constexpr B s2{s1};
}
Run Code Online (Sandbox Code Playgroud)