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

6
在以下代码中,我试图存储对另一个类的const引用:
struct A {
};

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

int main() {
    constexpr A s1;
    constexpr B s2{s1};
}

然而,编译器(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};
      |

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

  1. s1为什么不是常量表达式?
  2. 处理这种情况的最佳实践是什么?

非常感谢!


https://godbolt.org/z/bf8TnYMss - Marek R
1个回答

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

因此,您需要在这里添加一个 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};
}

自clang 12起,早期版本不包含该信息。 - Marek R
@MarekR 刚刚检查了 v11.0.1,你是对的。为了清晰起见,编辑以添加版本号,谢谢 :) - mediocrevegetable1

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