Question: Why doesn’t the same piecewise constructibility exist for arrays and tuples?
My recollection is that piecewise construction was added to std::pair
for one reason only: to support uses-allocator construction of the pair elements, i.e. to allow an allocator to be provided and conditionally passed to the elements if they support construction with an allocator (see [allocator.uses] in the standard).
At one point during the C++0x process std::pair
had twice as many constructors as it does now, with every constructor having a corresponding “allocator-extended” version taking a std::allocator_arg_t
and an allocator argument e.g.
template<class T, class U>
struct pair {
pair();
pair(allocator_arg_t, const Alloc&);
template<class TT, class UU>
pair(TT&&, UU&&);
template<class Alloc, class TT, class UU>
pair(allocator_arg_t, const Alloc&, TT&&, UU&&);
// etc.
There was something of a running joke (haha, only serious) about the insane complexity of std::pair
. The support for passing allocators to the elements was removed from std::pair
and moved into std::scoped_allocator_adaptor
, which is responsible for detecting whether the elements should be constructed with an allocator (see the construct
overloads taking a pointer to std::pair
in [allocator.adaptor.members]).
A nice consequence of the piecewise construction is that you can do “emplace” style initialization of pair elements, allowing pairs of non-movable, non-copyable types, but as far as I know that was not the goal of the design.
So the reason tuple
doesn’t support it is that the feature was invented to simplify pair
which had ballooned from a very simple type in C++03 to a laughing stock in C++0x, but doing the same for tuple
was not considered as important (it was new for C++11 anyway). Also, extending scoped_allocator_adaptor
to handle tuples of arbitrary numbers of elements would have made that adaptor much more complicated.
As for std::array
, that’s an aggregate type (because reasons) so adding a constructor taking piecewise_construct_t
is not possible without making it a non-aggregate.