首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >允许std::tuple的实现失败并触发空类元素的派生到基类的转换吗?

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

Stack Overflow用户
提问于 2012-12-16 23:45:40
回答 2查看 428关注 0票数 18

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

代码语言:javascript
复制
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++的一个错误?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2012-12-17 18:45:09

根据第17条库简介

17.5.2.3私有成员objects.within.classes

1-第18至30条和附件D没有规定类别的表示,并故意省略了类别成员的说明。实现可以根据需要定义静态和/或非静态类成员,以实现第18至30条和附件D中指定的成员函数的语义。

1.4 Implementation compliance intro.compliance支持此功能

3-对于类和类模板,library子句指定部分定义。没有指定私有成员(第11条),但每个实现都应提供它们,以根据库子句中的描述完成定义。

通过继承实现指定的语义在第17条中没有明确讨论,但通过上面17.5.2.3的第3段隐含地允许:

3-实现可以使用任何提供等效外部行为的技术。

例如,这就是基于节点的有序关联容器如何通过继承共享实现细节(最终包括类成员)的方式。

由于tuple的外部行为在将A作为类成员和直接继承它之间进行了更改,并且由于这种行为更改会导致拒绝其他格式良好的程序(而不仅仅是更改类的sizeof ),因此libstdc++违反了标准。

票数 2
EN

Stack Overflow用户

发布于 2012-12-17 00:07:05

我会说no

至少:

§20.4.1 tuple.general

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

然而:

代码语言:javascript
复制
#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()));
}

fails具有以下特性:

代码语言:javascript
复制
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节是相当简洁的……

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/13902910

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档