繁体   English   中英

是否允许std :: tuple的实现失败并触发空类元素的派生到基础转换?

[英]Is an implementation of std::tuple allowed to fail with triggering a derived-to-base conversion for empty class elements?

此代码不能使用GCC4.7进行编译

struct A {};
void f(A);

struct B { B(std::tuple<A>); };
void f(B);

int main() {
  f(std::make_tuple(A()));
}

因为GCC派生自A来利用空基类优化。 然而,这导致GCC选择f(A)并抱怨

错误: 'A''tuple<A>'无法访问的基础

这个错误是由C ++标准授予的,还是仅仅是libstdc ++的错误?

我会说不

至少:

§20.4.1[tuple.general]

1 / [...]具有两个参数的元组实例化类似于具有相同两个参数的对的实例化。 见20.3。

但是:

#include <tuple>

struct A {};
void f(A);

struct B { B(std::tuple<A, A>); };
void f(B);

int main() {
  f(std::make_tuple(A(), A()));
}

失败了:

Compilation finished with errors:
source.cpp: In function 'int main()':
source.cpp:10:30: error: 'A' is an ambiguous base of 'std::tuple<A, A>'
source.cpp:4:6: error: initializing argument 1 of 'void f(A)'

我非常怀疑这是标准的意图。

不过,至少可以说§20.4相当简洁......

根据第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 ++是违反标准。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM