C ++ 11-C ++ std :: tuple销毁顺序

是否有规则说明std :: tuple的成员按什么顺序销毁?

例如,如果Function1返回std::tuple<std::unique_ptr<ClassA>, std::unique_ptr<ClassB>>Function2,那么我可以确定(当保留Function2的范围时)第二个成员引用的ClassB实例在第一个成员引用的ClassA实例之前被销毁了吗?

std::tuple< std::unique_ptr< ClassA >, std::unique_ptr< ClassB > > Function1()
{
    std::tuple< std::unique_ptr< ClassA >, std::unique_ptr< ClassB > > garbage;
    get<0>(garbage).reset( /* ... */ );
    get<1>(garbage).reset( /* ... */ );
    return garbage;
}

void Function2()
{
    auto to_be_destroyed = Function1();
    // ... do something else

    // to_be_destroyed leaves scope
    // Is the instance of ClassB destroyed before the instance of ClassA?
}
z32a7ul asked 2020-06-23T06:27:10Z
3个解决方案
53 votes

针对您的问题,我将提供我所学的人生课程,而不是直接的答案:

如果您可以为多种替代方案制定一个合理的论据,说明为何该替代方案应成为标准规定的替代方案-那么您不应假定其中的任何替代方案都是强制性的(即使其中一种恰好是强制性的)。

在元组的上下文中,请对维护您的代码的人保持友好,不要让元组元素的破坏顺序潜在地破坏其他元素的破坏。 那真是邪恶……想像一下不幸的程序员将需要调试这个东西。 实际上,几年后,当您已经忘记了过去的聪明技巧时,那个可怜的灵魂可能就是您自己。

如果您绝对必须依赖销毁顺序,那么也许您应该只使用一个适当的类,将元组的元素作为其数据成员(可以编写一个析构函数,以明确需要按什么顺序发生什么),或者其他一些方法 安排有助于更明确地控制销毁。

einpoklum answered 2020-06-23T06:28:26Z
35 votes

该标准未指定std::tuple的销毁顺序。§20.4.1/ p1指出以下事实:

具有两个参数的元组实例化类似于 具有相同两个参数的对的实例化。

此处类似的内容不解释为相同,因此不暗示std::tuple应该具有其参数的反向销毁顺序。

鉴于std::tuple的递归性质,最可能的是破坏的顺序与其论据的顺序是一致的。

我的假设也基于GCC BUG 66699的错误报告,在讨论中我的上述假设是合理的。

也就是说,未指定std::tuple的销毁顺序。

101010 answered 2020-06-23T06:27:52Z
13 votes

使用Clang 3.4,对于std::pair和2个元素std::tuple,我得到相同的销毁顺序;对于g ++ 5.3,我得到相反的顺序,这可能主要是由于libstd ++中std::tuple的递归实现。

因此,它基本上可以归结为我在评论中所说的,它是实现定义的。

从BUG报告中:

Martin Sebor的评论

由于完全指定了std :: pair成员的布局,因此 它们的初始化和销毁顺序。 测试的输出 大小写反映了此顺序。

std:stuple子对象的初始化(和销毁)顺序 不太明确地指定。 至少从以下情况来看不是立即显而易见的 如果需要任何特殊订单,请阅读我的规格说明。

libstdc ++的std :: tuple输出的原因是相反的 std :: pair的原因是因为实现依赖于递归 反向继承,存储和构造元组元素 顺序:即存储最后一个元素的基类 并首先构造,然后是每个派生类(每个类 存储最后-第N个元素)。

错误报告程序引用的标准[第20.4.1节]中的引用

1本节描述了提供元组的元组库 type作为可以用任何实例化的类模板元组 参数数量。 每个模板参数都指定了 元组中的元素。 因此,元组是异构的 固定大小的值集合。 两个元组的实例化 参数类似于具有相同两个的对的实例化 论点。 见20.3。

链接错误中对此的争论是:

被描述为相似并不意味着它们在每个方面都是相同的 详情。 std :: pair和std :: tuple是不同的类 每个要求。 如果您认为要求行为 在这方面完全相同(即,在 同样的顺序),您需要指向特定的措辞 保证它。

Arunmu answered 2020-06-23T06:29:32Z
translate from https://stackoverflow.com:/questions/39068546/c-stdtuple-order-of-destruction