gpt4 book ai didi

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

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:16:12 26 4
gpt4 key购买 nike

我想定义派生类型 (SBar) 的 constexpr 值,使用构造函数,其唯一参数是基类 (SFoo) 的变量,它仅用于初始化基类。

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

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

测试.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 可以提供帮助,但我宁愿使用 native 数组并理解潜在的问题)。

最佳答案

所以对于 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.常量]

据我对 12.8p26 节的阅读所知,隐式定义的复制/移动赋值应该是 constexpr。所以 gcc 在这里似乎不正确。

关于c++ - 如果基类包含数组成员,则派生类的构造函数不能是 constexpr,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34097076/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com