user10889578
user10889578

Reputation:

Fold expression as argument of [] operator

I am trying to use a fold expression as the argument of the [] operator. Unfortunately, only the first element is correct.

template <class ...U> T& operator[](U ...indices){
    size_t i=0, k[get_n_dimensions()];
    (... , void(k[i++]=indices));
    // use k[0], k[1], ...
    // only k[0] is correct
}

However, if I use the same syntax for the argument of a function, it works fine.

template <class ...U> T get(U ...indices) const {
    size_t i=0, k[get_n_dimensions()];
    (... , void(k[i++]=indices));
    // k[0], k[1], ... filled correctly
}

What is the reason? What would be the solution?

Upvotes: 2

Views: 472

Answers (3)

AndyG
AndyG

Reputation: 41145

As others have mentioned, the subscripting operator operator[] must accept only a single parameter.

See [over.sub] (emphasis mine)

operator[] shall be a non-static member function with exactly one parameter. It implements the subscripting syntax

However, that one parameter doesn't have to be an integer.

You could still do what you want if you are able to move your values into a std::index_sequence like so:

template<size_t... indices>
T& operator[](std::index_sequence<indices...>){
    size_t i=0, k[get_n_dimensions()];
    (... , void(k[i++]=indices));
    // ...
}

You'd call it like so

my_instance[std::make_index_sequence<3>{}]; // passes 0, 1, 2 to the function

Live Demo

Upvotes: 0

molbdnilo
molbdnilo

Reputation: 66459

C++ does not have multi-dimensional indexing, and that's "hard-wired" into the syntax - you can't add it by overloading.

The reason that your code compiles at all is that p[a,b] is equivalent to p[(a,b)] - that is, it uses the regular comma operator which will compute a and ignore the result, then produce the value of b as the index into p.

Thus, your template is never used "variadically", but is essentially the same as

template <class U> T& operator[](U indices)

You need to name the function, or overload an operator that can take more than one parameter, such as operator().

Upvotes: 4

Vittorio Romeo
Vittorio Romeo

Reputation: 93364

What is the reason?

The array subscript operator (operator[]) must have exactly one argument. The first snippet you have shown is invalid for any sizeof...(U) != 1.

A function template like get or another operator like operator() do not have a similar limitation.


What would be the solution?

Do not use operator[].

Upvotes: 7

Related Questions