C++ Logo


Advanced search

Re: [std-proposals] Making tuple an aggregate

From: Arthur O'Dwyer <arthur.j.odwyer_at_[hidden]>
Date: Tue, 7 Jun 2022 10:42:32 -0700
On Tue, Jun 7, 2022 at 9:55 AM Phil Endecott via Std-Proposals <
std-proposals_at_[hidden]> wrote:

> Today I have been frustrated by std::tuple not being an aggregate.
> I have some non-moveable types and it is difficult to use them
> with tuples. That's in contrast to std::pair, which I can use
> with piecewise_construct [...]
> std::pair<NonMoveable,NonMoveable> p{ std::piecewise_construct,
> std::make_tuple(1,2),
> std::make_tuple(3,4) };
> std::tuple<NonMoveable,NonMoveable> t .....????.....
> So, what can we do to make std::tuple more like a struct?
> One obvious "fix" would be to add std::piecewise_construct support
> to std::tuple.

Yes. And I think this is a good idea; I would be willing to help write a
proposal for it, unless someone else knows a good reason that a previous
attempt failed. (It seems unlikely that this idea has *never* occurred to
anyone before now!)

Why is std::pair piecewise-constructible, but std::tuple didn't need to be?
Apparently the reason is that std::pair is std::map::value_type, so in
order to make uses-allocator construction work, std::pair needed a way to
forward arguments to both of its pieces individually. std::tuple is never
used in that special way as a value_type, so it didn't need piecewise

As the SO comments correctly point out: There is no way to make a type be
piecewise-constructible *and* an aggregate at the same time.
Piecewise-constructibility requires that you have that specific
constructor, and aggregateness requires that you have *no* constructors.
(Tuple has many, many constructors already, so it will never ever be an
aggregate. You can give up on that possibility.)

template <typename... TYPES>
> struct tuple {
> TYPES fields;...
> };
> I note that we can use pack expansion with ",". Why not also with ";" ?

Because grammar. `...` goes *inside* an expression or
expression-like-thingie, at the point where you want the expansion to take
place. Semicolons by definition *separate* those thingies. However, this
isn't a problem for what you want to do, because the actual syntax for what
you want to do would be

    template<class... Ts>
    struct AggregatePseudoTuple {
        Ts... fields;

AIUI, the next problem you'd have to overcome (and the reason this isn't in
the language quite yet) is figuring out how to *name* one of those fields.
Barry Revzin has proposed at least one syntax for indexing-into-a-tuple, so
maybe one day you'd be able to say something like

    template<size_t K, class... Ts>
    decltype(auto) get(AggregatePseudoTuple<Ts...>& t) {
        return t.fields...[K]; // P1858r2's syntax, if I understand

(Barry Revzin)

Barry's copious review-of-literature at the end of P1825 includes these
earlier papers:
- https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4235.htm
(Daveed Vandevoorde)
- https://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0535r0.html
(Matthew Woehlke)


Received on 2022-06-07 17:42:44