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.
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.
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.
The new std::array and std::tuple containers provide developers with additional ways to manage structured data efficiently.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With