6

std::tuple is highly template-loaded beast. To access to n-th member compiler must perform a plenty of template instantiations, although its simple nature: access to n-th data member of corresponding imaginary struct. It seems that std::tuple should be a core language feature, something like this (pseudocode):

template< typename ...types >
struct/* or class, or even union */ V
{
    types... V; // defines implicitly `operator [/*constant expression*/]` to access by index
    // if more than one variadic parameter pack provided
    // (during expanding of parameter pack of template 
    // parameters in specializations) then instead of
    // `V` there can be specific data-member name (say, `x`),
    // but still with `x.operator []` implicitly defined

    // member functions and data members allowed
};

template< typename ...types >
V< std::decay_t< types >... > make_tuple(types &&... args)
{ return {std::forward< types >(args)...}; }
template< typename ...types >
V< types &&... > forward_as_tuple(types &&... args)
{ return {std::forward< types >(args)...}; }
template< typename ...types >
V< types &... > tie(types &... args)
{ return {args...}; }

Is there any proposal of something like language supported variadic data-members definition syntax for classes?

Tomilov Anatoliy
  • 15,657
  • 10
  • 64
  • 169
  • 1
    What is the advantage of making it core-language feature? why only `std::tuple`? why not `std::vector` also? My thought is that if something can be done as library feature, it should be done, *only if* that is not possible (or too hacky to do that) it makes sense to add it language feature. – Nawaz Oct 02 '15 at 12:02
  • @Nawaz POD array (single type, multiple values) already present in language, `int x[3] = {1, 2, 3};`. – Tomilov Anatoliy Oct 02 '15 at 12:03
  • 1
    Regardless about `types... V;`, `operator[](size_t)` cannot possibly exist. – Barry Oct 02 '15 at 12:04
  • @Barry above syntax is just *my* proposal. I want to see a real proposal maden by professionals from the Committee. BTW, C-arrays has `operator []` implicitly defined in some sense and C-structs has operator `.` to access to data members. – Tomilov Anatoliy Oct 02 '15 at 12:09
  • @Barry OK, instead of `[]` I can propose a variable template-like syntax via `< std::size_t >`. – Tomilov Anatoliy Oct 02 '15 at 12:12
  • 3
    @Nawaz, have you looked at the definition of `std::tuple` recently? It's disgusting. A core language feature would just do the right thing. I've been threatening to propose something like this for a while. – Jonathan Wakely Oct 02 '15 at 12:15
  • C++ core language is a beast. It's high time to start removing features from it. – n. m. could be an AI Oct 02 '15 at 13:12
  • @JonathanWakely Just have to state that you can declare variables of type pack expansion and throw in some wording about how `T... v;` is equivalent to `T0 v0; T1 v1; T2 v2; ... Tn vn;`? – Barry Oct 02 '15 at 13:23
  • 2
    @Barry rather, it should be equivalent to `T.[0] v<0>; .. T.[n] v;` [using n4235](http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4235.htm) -- ie, I'd have it define a variable template (!) `template T.[n] v;` You'd then access the variable template the way you'd access any other variable template. Of course, variable templates in structs are not currently allowed, but a variable template with explicit instantiation should be viable in a `struct`... So, template member variables, and a syntax to declare a subset of them... – Yakk - Adam Nevraumont Oct 02 '15 at 13:55

1 Answers1

9

See N4235 Selecting from Parameter Packs for a related idea.

That might be useful for std::tuple, but I'm more interested in a feature to simplify its construction, not selection of members (which is comparatively simple).

The definition of std::tuple is insanely complicated, in order to make all the constructors correctly model the properties of all the members (see N4064 for the most recent changes in that area).

When you use aggregate-initialization the compiler automatically checks whether each member of the aggregate can be constructed from the corresponding initializers. It checks for suitable constructors, whether they are explicit, accept the relevant lvalue/rvalue category etc.

When you define a constructor for std::tuple is has to be very complicated to ensure that only valid conversions happen, that explicit constructors are not used when they shouldn't be etc.

I'd like a feature that made it much easier to automatically generate suitable constructors to model the same semantics as you get for free from aggregate initialization.

Jonathan Wakely
  • 166,810
  • 27
  • 341
  • 521