c – 如果基类包含数组成员,派生类的构造函数不能是constexpr

c – 如果基类包含数组成员,派生类的构造函数不能是constexpr,第1张

概述我想使用构造函数定义派生类型(SBar)的constexpr值,该构造函数的唯一参数是基类(SFoo)的变量,它只是用于初始化基类. 当基类没有数组成员时,这很好用.但是,当我添加一个数组时,派生值不能再是constexpr.但是,基类的简单副本确实会产生constexpr结果. 为了安全起见,我明确默认了所有复制和移动构造函数. TEST.CPP #define USE_ARRAYstru 我想使用构造函数定义派生类型(Sbar)的constexpr值,该构造函数的唯一参数是基类(SFoo)的变量,它只是用于初始化基类.

当基类没有数组成员时,这很好用.但是,当我添加一个数组时,派生值不能再是constexpr.但是,基类的简单副本确实会产生constexpr结果.

为了安全起见,我明确默认了所有复制和移动构造函数.

TEST.CPP

#define USE_ARRAYstruct 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;#       endifconstexpr 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 Expressionconstexpr 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在这里似乎不正确.

总结

以上是内存溢出为你收集整理的c – 如果基类包含数组成员,派生类的构造函数不能是constexpr全部内容,希望文章能够帮你解决c – 如果基类包含数组成员,派生类的构造函数不能是constexpr所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1228006.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存