The standard templates std::pair
and std::array
are special cases of std::tuple
, and it stands to reason that they should have a very similar set of capabilities.
However, uniquely among the three, std::pair
allows for piecewise construction. That is, if the types T1
and T2
can be constructed from a set of arguments a1, a2, ...
and b1, b2, ...
, then morally speaking we can make a pair
"pair<T1, T2> p(a1, a2, ..., b1, b2, ...)"
directly. Practically, this is spelt out as something like this:
std::pair<T1, T2> p(std::piecewise_construct,
std::forward_as_tuple(a1, a2, ...),
std::forward_as_tuple(b1, b2, ...));
Question: Why doesn't the same piecewise constructibility exist for arrays and tuples? Is there a profound reason, or is this a plain omission? For example, it would be nice to have:
std::tuple<T1, T2, T3> t(std::piecewise_construct,
std::forward_as_tuple(a1, a2, ...),
std::forward_as_tuple(b1, b2, ...),
std::forward_as_tuple(c1, c2, ...));
Is there a reason this cannot be done? [Edit: Or am I misunderstanding the purpose of piecewise construction entirely?]
(I do really have a situation in which I would like to initialize a vector of tuples with a defaulted element value which I would prefer to construct directly from the arguments, without spelling out each tuple element type again.)
std::array
supports the "tuple-like access" interface but there the similarity ends. There is also no piecewise construction there, nor can there be as it's an aggregate and can't have explicit constructors. – Moldboost::in_place
's intoemplace_back
. – Cotilliontuple_size
andelement_type
traits; they have iterators, andget
accessors. It's true thatarray
has additional details (contiguous memory, aggregate, and[]
-accessor), though. – Cosmogonystd::pair
also supports reference members, and will misbehave, binding a member reference to a temporary when you try to piecewise construct a const lvalue or rvalue reference member. EDIT: Maybe that's not a problem, since the user might want that when the resulting tuple is also a temporary. – Moldforward_as_tuple
s. I never used that one before! :-) – Cosmogonystd::make_pair
andstd::make_tuple
, as well as the much-missedmake_array
that should really exist... – Cosmogonystd::array
, it has no constructors, and defining one would prevent it from being an aggregate. – Purushamake_array
does not requirearray
to have constructors --I don't thinkmake_array
is needed, but the lack of constructors would not be a reason not to havemake_array
– Throesmake_array
, but I was more thinking about a piecewise_construct constructor forstd::array
– Purushaarray
can't get a constructor, but conversely, themake_
functions don't make sense with piecewise arguments, since the whole point of them is to deduce the element type.make
andpiecewise
are mutually exclusive concepts. – Cosmogony