c++ - constexpr 和 mutable 成员和隐式 copy-ctor
问题描述
以下代码在 clang 7+ 中编译,但不在 5 和 6 中编译(使用 c++17 和 c++14)。clang 5 和 6 的问题似乎是隐式复制 ctor 从 mutable member 读取x
。
谁能告诉我,整个结构是否符合标准(c++17),或者程序是否格式错误?还是在早期的 clang 版本中可能无法实现的隐式复制ctor 的标准发生了变化?
struct Foo {
int a;
mutable int x{};
constexpr Foo() : a(0) {}
//constexpr Foo(const Foo& other) : a(other.a) {} // <- with this line it works on Clang 5 & 6, too
};
struct FooFactory {
static constexpr auto create() {
auto f = Foo{};
return f;
}
};
int main() {
constexpr Foo f = FooFactory::create();
++f.x;
}
现场代码在这里。
解决方案
这是一个格式良好的 C++17 程序。constexpr 函数当然可以读取(和写入)非常量变量:
constexpr int f(int i) {
int j=i;
++j;
return i+j; // neither is a constant expression
}
规则是,在常量表达式中检查的任何内容都必须是常量,或者在表达式求值期间开始其生命周期。在您的情况下,create
's的生命周期f.x
显然始于对常量表达式的评估,即's的初始化。然而,确实没有对象可以被不创建该对象的常量表达式复制,无论它是否是.main
f
Foo
constexpr
唯一的其他候选问题是如果复制构造函数不是 constexpr,但这些要求非常弱。唯一相关的是每个(非变体)成员都被初始化,这肯定是令人满意的,并且它可以在至少一个常量表达式中使用,这已经被证明了。
推荐阅读
- visual-studio - 有没有办法设置键盘快捷键以在 Visual Studio 的解决方案资源管理器中打开包含选定文件的文件夹?
- python-3.x - Python:从列表中检索信息
- python-3.x - pytest中测试的条件参数化
- node.js - 如何在 NestJs 和 typescript 中使用 `mongoose-delete` 插件?
- plugins - tinymce 5 换行插件
- java - javax.servlet 的 OSGI 兼容性
- objective-c - 设计具有双向通信通道的 XPC 服务
- javascript - 如何在本机反应中调整屏幕不同位置的单个组件?
- python-3.x - 如何在具有不同形状行的 numpy 数组中找到唯一行?
- visual-studio-code - VSCODE - 滚动浏览带有图片的 .ipynb 是 JUMPY