Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
244 views
in Technique[技术] by (71.8m points)

c++ - Why is there no piecewise tuple construction?

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.)

question from:https://stackoverflow.com/questions/11846634/why-is-there-no-piecewise-tuple-construction

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...