是否存在一条规则,说明std :: tuple的成员以哪种顺序被销毁?
例如,如果 SELECT colA,
colB,
(CASE When `date` < str_to_date('2016-01-01', '%Y-%m%d') then 'daterange A'
When `date` < str_to_date('2016-01-02', '%Y-%m%d') then 'daterangeB'
When `date` < str_to_date('2016-01-03', '%Y-%m%d') then 'daterangeC'
When `date` < str_to_date('2016-01-04', '%Y-%m%d') then 'daterangeD'
END) AS colG
FROM (SELECT colA, colB, `date` FROM table1
UNION ALL
SELECT colD, colE, `date` FROM table2
) my_t;
返回Function1
到std::tuple<std::unique_ptr<ClassA>, std::unique_ptr<ClassB>>
,那么我可以确定(当Function2
的范围留下时){{1}的实例在第一个成员引用的Function2
实例之前销毁第二个成员引用的?
ClassB
答案 0 :(得分:53)
我会在回答你的问题时提供我已经学到的生活课程,而不是直接的答案:
如果您可以为多种替代方案制定一个合理的论据,说明为什么该替代方案应该是标准规定的方案 - 那么您不应该假设任何强制要求(即使其中一个他们碰巧是)。
在元组的上下文中 - 请,请善待维护代码的人,不要让元组元素的破坏顺序可能会破坏其他元素的破坏。这只是邪恶......想象一下需要调试这个东西的不幸的程序员。事实上,这个可怜的灵魂可能在几年内就会成为你自己,当时你已经忘记了当时的聪明伎俩。
如果你绝对必须依赖于破坏顺序,也许你应该只使用一个正确的类,将元组的元素作为其数据成员(你可以编写一个析构函数,明确需要发生什么)什么顺序),或其他一些促进更明确控制破坏的安排。
答案 1 :(得分:35)
标准未指定std::tuple
的销毁顺序。 §20.4.1/ p1指定的事实:
具有两个参数的元组实例化类似于 具有相同两个参数的对的实例化。
类似此处不会被解释为相同,因此并不意味着std::tuple
应该具有其参数的反向销毁顺序。
鉴于std::tuple
的递归性质,最可能的是破坏的顺序与其参数的顺序是一致的。
我的假设基于GCC BUG 66699的错误报告,在讨论中我的假设是合理的。
也就是说,std::tuple
的销毁顺序未指定。
答案 2 :(得分:13)
使用Clang 3.4我得到std::pair
和2个元素std::tuple
的相同破坏顺序,并且使用g ++ 5.3我得到相反的顺序,这可能主要是由于std::tuple
的递归实现在libstd ++。
所以,它基本上归结为我在评论中所说的内容,它是实现定义的。
来自BUG报告:
Martin Sebor的评论
由于完全指定了std :: pair成员的布局,因此也是如此 他们的初始化和破坏的顺序。测试的输出 案例反映了这个顺序。
std:stuple子对象的初始化(和销毁)顺序 没有明确规定。至少它并不是立竿见影的 如果需要任何特定订单,我会阅读规范。
使用libstdc ++的std :: tuple的输出是相反的 std :: pair是因为实现,它依赖于递归 继承,反向存储和构造元组元素 order:即,存储存储最后一个元素的基类 并首先构建,然后是每个派生类(每个派生类) 存储最后一个 - 第N个元素。)
臭虫记者引用的标准[第20.4.1节]的引用
1本小节描述了提供元组的元组库 键入可以用any实例化的类模板元组 参数的数量。每个模板参数指定一个类型 元组中的元素。因此,元组是异构的, 固定大小的值集合。 有两个元组的实例化 参数类似于具有相同两个的对的实例化 参数即可。见20.3。
链接错误中对此的争论是:
被描述为类似并不意味着它们在每一个都是相同的 详情。 std :: pair和std :: tuple是不同的不同类 每个要求。如果您认为必须表现出来 在这方面完全相同(即,在其中定义其子对象) 相同的顺序)你需要指出具体的措辞 保证它。