Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Are std::tuple and std::tuple<std::tuple> considered same type by std::vector?

Tags:

c++

tuples

I have a variable defined like this

auto drum = std::make_tuple
          ( std::make_tuple
          ( 0.3f
          , ExampleClass
          , [](ExampleClass& instance) {return instance.eGetter ();}
          )
          );

I expect drum to be a tuple of tuple. (i.e. ((a, b, c))).

And I have another variable defined like this

auto base = std::make_tuple
          ( 0.48f
          , ExampleClass
          , [](ExampleClass& instance) {return instance.eGetter ();}
          );

which I expect to be just a tuple of three elements (i.e (a, b, c))

I also have a vector defined as follows

std::vector<std::tuple<std::tuple< float
                                 , ExampleClass
                                 , std::function<float (ExampleClass&)>
                                 >>> listOfInstruments;

Now if I add drum to listOfInstruments I expect no errors.

Which was indeed the case with listOfInstruments.push_back(drum);

Where I expected an error was here listOfInstuments.push_back(base); but the code compiles just fine.

Since listOfInstruments has type 'tuple of tuples', should't adding just 'tuple' cause some error? Unless both () and (()) are considered same types by std::vector. Or am I completely wrong and there's something else at work here?

Can't seem to figure it out.

like image 258
atis Avatar asked Jan 22 '19 10:01

atis


People also ask

Can tuple have different data types C++?

Tuples in C++ A tuple is an object that can hold a number of elements. The elements can be of different data types. The elements of tuples are initialized as arguments in order in which they will be accessed.

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 std :: tuple a container?

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

Are there tuples in CPP?

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.


1 Answers

Tuples and vectors are mostly red herrings here. The way that works is simply that push_back, like any function, can perform implicit conversions on its argument, as demonstrated by the following working snippet:

#include <vector>

struct A { };

struct B {
    B(A const &) { }
};

int main() {
    std::vector<B> v;
    v.push_back(A{});
}

Going back to tuple, we can see that it has (among others) a conditionally-explicit constructor (#2 here) which takes references to the tuple's members-to-be:

tuple( const Types&... args );

This constructor is implicit if and only if all of the members have implicit copy constructors, which is the case here (as synthesized constructors are implicit indeed). This means that std::tuple<...> is implicitly convertible to std::tuple<std::tuple<...>>, which is what you're observing.

like image 119
Quentin Avatar answered Sep 18 '22 09:09

Quentin