【发布时间】:2016-07-23 11:01:47
【问题描述】:
给定struct B,它从struct A 继承了一个匿名的union 数据成员:
#include <cstddef>
struct A
{
union
{
struct { int a, b, c; };
int vals[3];
};
};
struct B: A
{
constexpr B(int x)
:
A{{{ x, x, x }}}
{}
constexpr int& operator[](size_t i)
{
return this->vals[i];
}
constexpr const int& operator[](size_t i) const
{
return this->vals[i];
}
};
我声明了一个B 类型的constexpr 变量,然后调用它的operator[] 将返回值分配给constexpr int:
int main()
{
constexpr B b(7);
constexpr int i = b[2];
return 0;
}
但是 Clang 3.8 给了我错误信息
constexpr variable 'i' must be initialized by a constant expression
这个问题与匿名 union 有关,因为当我简单地使用 int vals[3] 时,一切正常。
我缺少 C++14 constexpr 限制吗?
【问题讨论】:
-
肯定和工会有关。 gcc 5.3.1 在 "A{ x, x, x }" 初始化程序上发牢骚——错误:无法将'x'从'int'转换为'A::
' -
有趣,Clang 没有抱怨初始化。 A 是否违反聚合初始化规则?
-
好吧,在折腾之后,如果我给联合一个正式的字段名称:“union { ... } u;”,然后声明一个显式构造函数:“A(int aa,int bb , int cc) : u{aa, bb, cc}{}",gcc 5.3.1 接受该部分,但随后出现了关于 constexpr 运算符 []s 的重大故障。 “错误:constexpr 非静态成员函数‘int& B::operator[](size_t)’的封闭类不是文字类型”。我自己并不确定这整件事。无法将我的大脑完全包裹在 constexpr 运算符 [] 周围,这样做。
-
@SamVarshavchik 不知道为什么,但看起来 GCC 坚持使用 A({x, x, x}) 而不是 A{x,x,x} 或 A{{x,x, x}},所以我更新了我的答案。但是,是的,它对原始问题没有任何作用。
-
好的,我对代码进行了测试,而 gcc 5.3.1 吞下了整件事。因此,通过适当的殴打和折磨,gcc 5.3.1 将接受这一点。编辑:只是声明,gcc 仍然有 main() 的问题。
标签: c++ c++11 c++14 unions c++17