C++ 结构化绑定:标准的销毁顺序是什么?

Tee*_*eej 2 c++ c++17

是否有可以放入结构化绑定语句中的方法返回的对象的销毁顺序的定义?cppreference 似乎没有提到销毁顺序,并且对 godbolt 的快速测试揭示了一些与我预期不同的内容。

#include <iostream>
#include <tuple>

struct A{
    A()=default;
    ~A(){ std::cout << "~A()" << std::endl; }
};

struct B{
    B()=default;
    ~B(){ std::cout << "~B()" << std::endl; }

};

struct C{
    C()=default;
    ~C(){ std::cout << "~C()" << std::endl; }
};

auto MakeStuff()
{
    auto a = A{};
    auto b = B{};
    auto c = C{};
    
    return std::make_tuple(std::move(c), std::move(b), std::move(a));
}

int main()
{
    auto&& [c, b, a] = MakeStuff();
    std::cout << "Results now: " << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

结果:

Program returned: 0
~C()
~B()
~A()
Results now: 
~C()
~B()
~A()
Run Code Online (Sandbox Code Playgroud)

我猜想结构化绑定从右到左构造 [括号] 中的对象,看看析构函数如何调用为cfirst、then b、then a。这是标准行为,还是我依赖​​于特定于实现的东西?

谢谢。

Nic*_*las 9

结构化绑定在构造/破坏的顺序方面绝对不会改变语言。get<I>(unnamed_object)结构化绑定是一种虚构,是一种将或unnamed_object.some_name变成 的语言速记some_name。在本小说中,unnamed_object是由表达式生成并由结构化绑定声明捕获的实际对象auto[]

该对象的工作方式与任何其他 C++ 对象完全相同。类中子对象声明的顺序(如果它是一个类)决定了构造和销毁的顺序,就像任何其他 C++ 对象一样。

现在,当谈到 时std::tuple,其子对象声明的顺序是未指定的;允许不同的实施方式有所不同。同样,结构化绑定与此无关。因此,销毁的顺序可以是您的特定实现想要的任何顺序。

  • @Teeeeeeeeeeeeeeeeeeeeeeeeeeeeeej 有一些标准库实现按照模板参数的顺序存储 `std::tuple` 元素,还有一些以相反的顺序存储它们。因此,对我来说,这似乎不太可能被标准化,因为它会强制其中之一出现“std::tuple” ABI 中断。程序不应依赖于顺序。如果您想要特定的顺序,则可以使用自定义聚合类。它们还可以使用结构化绑定。这样您就可以选择订单了。 (2认同)