c – 如果基类包含数组成员,派生类的构造函数不能是constexpr
发布时间:2020-12-16 07:14:38 所属栏目:百科 来源:网络整理
导读:我想使用构造函数定义派生类型(SBar)的constexpr值,该构造函数的唯一参数是基类(SFoo)的变量,它只是用于初始化基类. 当基类没有数组成员时,这很好用.但是,当我添加一个数组时,派生值不能再是constexpr.但是,基类的简单副本确实会产生constexpr结果. 为了安全
我想使用构造函数定义派生类型(SBar)的constexpr值,该构造函数的唯一参数是基类(SFoo)的变量,它只是用于初始化基类.
当基类没有数组成员时,这很好用.但是,当我添加一个数组时,派生值不能再是constexpr.但是,基类的简单副本确实会产生constexpr结果. 为了安全起见,我明确默认了所有复制和移动构造函数. TEST.CPP #define USE_ARRAY struct SFoo { constexpr SFoo() =default; constexpr SFoo(SFoo const&) =default; constexpr SFoo(SFoo &) =default; constexpr SFoo(SFoo &&) =default; constexpr SFoo& operator = (SFoo const&) =default; constexpr SFoo& operator = (SFoo &) =default; constexpr SFoo& operator = (SFoo &&) =default; # ifdef USE_ARRAY constexpr SFoo(int const (&array)[1]) : M_array{array[0]} {} int M_array[1] = {0}; # else constexpr SFoo(int value) : M_value{value} {} int M_value = 0; # endif }; struct SBar : SFoo { constexpr SBar() =default; constexpr SBar(SBar const&) =default; constexpr SBar(SBar &) =default; constexpr SBar(SBar &&) =default; constexpr SBar& operator = (SBar const&) =default; constexpr SBar& operator = (SBar &) =default; constexpr SBar& operator = (SBar &&) =default; constexpr SBar(SFoo foo) : SFoo(foo) {} }; // Instances: # ifdef USE_ARRAY constexpr int arg[1] = {3}; # else constexpr int arg = 3; # endif constexpr SFoo foo(arg); // base "value" constructor is constexpr. constexpr SFoo foo2(foo); // base copy constructor is constexpr. constexpr SBar bar(foo); // (line 54): this line fails. 用…编译 clang++ -std=c++1z -c -o test.o test.cpp 产量 test.cpp:54:16: error: constexpr variable 'bar' must be initialized by a constant expression constexpr SBar bar(foo); ^~~~~~~~ 1 error generated. 但是,如果我没有定义USE_ARRAY,一切都有效. 有谁知道为什么会这样? (我知道std :: array可以提供帮助,但我宁愿使用本机数组并理解底层问题). 解决方法
所以对于clang来说,看起来有一些修复方法.你可以改变:
constexpr SBar(SFoo foo) : SFoo(foo) {} 通过const引用获取foo: constexpr SBar(const SFoo &info) : SFoo(info) {} 似乎有效的另一个修复是注释掉sFoo中的以下复制构造函数: //constexpr SFoo(SFoo &) =default; 我没有立即看到C 1z标准草案中的语言使这种变化有意义. 另一方面,gcc抱怨复制构造函数说隐式定义不是constexpr(see it live),例如: error: explicitly defaulted function 'constexpr SFoo& SFoo::operator=(const SFoo&)' cannot be declared as constexpr because the implicit declaration is not constexpr constexpr SFoo& operator = (SFoo const&) =default; ^ 在我阅读7.1.5 [dcl.constexpr]和5.20 [expr.const]时,这对我来说并不明显. 据我在阅读第12.8p26节时可以看出,隐式定义的复制/移动分配应该是constexpr.所以gcc在这里似乎不正确. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |