Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ std::tuple order of destruction

Is there a rule which states in which order the members of an std::tuple are destroyed?

For example if Function1 returns an std::tuple<std::unique_ptr<ClassA>, std::unique_ptr<ClassB>> to Function2, then can I be sure that (when the scope of Function2 is left) the instance of ClassB referred to by the second member is destroyed before the instance of ClassA referred to by the first member?

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? } 
like image 973
z32a7ul Avatar asked Aug 21 '16 20:08

z32a7ul


People also ask

Are tuples immutable C++?

Tuples are immutable. Lists are mutable. Tuples can contain different data types. Lists consist of a singular data type.

What is a std :: tuple?

Class template std::tuple is a fixed-size collection of heterogeneous values. It is a generalization of std::pair. If std::is_trivially_destructible<Ti>::value is true for every Ti in Types , the destructor of tuple is trivial.

Is there tuple in C++?

Tuples are convenient in many circumstances. For instance, tuples make it easy to define functions that return more than one value. Some programming languages, such as ML, Python and Haskell, have built-in tuple constructs. Unfortunately C++ does not.

Is std :: tuple a container?

The new std::array and std::tuple containers provide developers with additional ways to manage structured data efficiently.


2 Answers

I'll offer a life lesson I've learned, rather than a direct answer, in response to your question:

If you can formulate, for multiple alternatives, a reasonable argument for why that alternative should be the one mandated by the standard - then you should not assume any of them is mandated (even if one of them happens to be).

In the context of tuples - please, please be kind to the people maintaining your code and do not allow the destruction order of tuple elements to potentially mess up the destruction of other elements. That's just evil... imagine the hapless programmer who will need to debug this thing. In fact, that poor soul might be yourself in a few years, when you've already forgotten about your clever trick from back-in-the-day.

If you absolutely must rely on destruction order, perhaps you should just be using a proper class with the tuple's elements as its data members (which you could write a destructor for, making it clear what needs to happen in what order), or some other arrangement facilitating a more explicit control of the destruction.

like image 87
einpoklum Avatar answered Sep 18 '22 12:09

einpoklum


The standard doesn't specify the order of destruction for std::tuple. The fact that §20.4.1/p1 specifies that:

An instantiation of tuple with two arguments is similar to an instantiation of pair with the same two arguments.

Similar here is not interpreted as identical and consequently it's not implied that std::tuple should have a reverse destruction order of its arguments.

Given the recursive nature of std::tuple most probable is that the order of destruction is in order with the order of its arguments.

I also base my assumptions on a bug report for GCC BUG 66699 where in the discussion my assumptions above are justified.

That said, the order of destruction for std::tuple is unspecified.

like image 20
101010 Avatar answered Sep 21 '22 12:09

101010