Joh*_*itb 18 c++ language-lawyer c++11 stdtuple
此代码不能使用GCC4.7进行编译
struct A {};
void f(A);
struct B { B(std::tuple<A>); };
void f(B);
int main() {
f(std::make_tuple(A()));
}
Run Code Online (Sandbox Code Playgroud)
因为GCC派生自A
利用空基类优化.然而,这导致海湾合作委员会挑选f(A)
和抱怨
错误:
'A'
是一个无法访问的基础'tuple<A>'
这个错误是由C++标准授予的,还是仅仅是libstdc ++的错误?
根据第 17 条图书馆介绍:
17.5.2.3 私有成员[objects.within.classes]
1 - 第 18 条至第 30 条和附录 D 未指定类别的表示,并有意省略类别成员的说明。根据需要实现第 18 条到第 30 条和附录 D 中指定的成员函数的语义,实现可以定义静态或非静态类成员,或两者。
1.4 实施合规性 [intro.compliance]支持这一点:
3 - 对于类和类模板,库子句指定部分定义。未指定私有成员(第 11 条),但每个实现应根据库条款中的描述提供它们以完成定义。
通过继承实现指定的语义没有在第 17 条中明确讨论,但通过上面 17.5.2.3 的第 3 段隐式允许:
3 - 实现可以使用提供等效外部行为的任何技术。
例如,这就是基于节点的有序关联容器如何通过继承共享实现细节(最终包括类成员)。
由于 的外部行为tuple
在作为类成员和直接继承它之间发生了变化A
,并且由于这种行为的变化会导致拒绝其他格式良好的程序(而不是仅仅更改类的sizeof
),因此 libstdc++ 违反了标准。