Allow multi-parameter overloads of operator[]

667 views
Skip to first unread message

daryl.va...@maptek.com.au

unread,
Oct 2, 2014, 11:38:32 PM10/2/14
to std-pr...@isocpp.org
The title is fairly self-explanatory. It would remove one excuse for overloading the comma operator and make multi-dimensional array access more efficient than what is achieved by using proxy classes.

Daniel Krügler

unread,
Oct 3, 2014, 6:55:49 AM10/3/14
to std-pr...@isocpp.org
Could you please elaborate on this? I don't think that the title alone
is self-explanatory. I would like to get a better understanding of
your suggested changes of the Standard.

- Daniel

David Krauss

unread,
Oct 3, 2014, 8:19:11 AM10/3/14
to std-pr...@isocpp.org
On 2014–10–03, at 6:55 PM, Daniel Krügler <daniel....@gmail.com> wrote:

Could you please elaborate on this? I don't think that the title alone
is self-explanatory. I would like to get a better understanding of
your suggested changes of the Standard.

The problem is the comma operator.

One solution would be to parse it as an operator when all the overloads found by name lookup have exactly one parameter, otherwise parse an argument list.

Deprecate the operator parse, let folks migrate. Proper migration can be verified by adding a void operator [] () = delete; declaration. Knock it out in the following standard revision.

Vittorio Romeo

unread,
Oct 3, 2014, 9:16:19 AM10/3/14
to std-pr...@isocpp.org
I guess that what he wants is something like this:

Vittorio Romeo


From: pot...@gmail.com
Subject: Re: [std-proposals] Allow multi-parameter overloads of operator[]
Date: Fri, 3 Oct 2014 20:18:54 +0800
To: std-pr...@isocpp.org
--

---
You received this message because you are subscribed to the Google Groups "ISO C++ Standard - Future Proposals" group.
To unsubscribe from this group and stop receiving emails from it, send an email to std-proposal...@isocpp.org.
To post to this group, send email to std-pr...@isocpp.org.
Visit this group at http://groups.google.com/a/isocpp.org/group/std-proposals/.

Vittorio Romeo

unread,
Oct 3, 2014, 9:18:27 AM10/3/14
to std-pr...@isocpp.org, daryl.va...@maptek.com.au
(Sorry for the double post, I misclicked.)

struct MultiDimArray
{
   
auto& operator[](std::size_t mX, std::size_t mY) // currently not valid
   
{
       
// ...
   
}
};

MultiDimArray mda;
mda
[1, 5] = 10;

I agree with this suggestion, it would be a nice addition to the language.

Agustín K-ballo Bergé

unread,
Oct 3, 2014, 10:07:31 AM10/3/14
to std-pr...@isocpp.org
On 03/10/2014 10:18 a.m., Vittorio Romeo wrote:
> (Sorry for the double post, I misclicked.)
>
> |
> structMultiDimArray
> {
> auto&operator[](std::size_t mX,std::size_t mY)// currently not valid
> {
> // ...
> }
> };
>
> MultiDimArraymda;
> mda[1,5]=10;
> |
>
> I agree with this suggestion, it would be a nice addition to the language.

This would be inconsistent with the way builtin arrays work. I would
expect the syntax to call that overloaded subscript operator to be
`mda[1][5]` instead. The other alternative, to change the way array
indexing works, would be a breaking change and a needless
incompatibility with C, so I think it would have a much lesser change of
success.

Until a proposal of the sort makes it into the language, consider the
following alternative:

struct mda_index { std::size_t x; std::size_t y; };

struct multi_dim_array {
auto& operator[](mda_index i) const { /*...*/ }
};

multi_dim_array mda;
mda[{1, 5}] = 10;

Regards,
--
Agustín K-ballo Bergé.-
http://talesofcpp.fusionfenix.com

Felipe Magno de Almeida

unread,
Oct 3, 2014, 10:23:55 AM10/3/14
to std-pr...@isocpp.org
Hello,

On Fri, Oct 3, 2014 at 11:07 AM, Agustín K-ballo Bergé
<kaba...@hotmail.com> wrote:
> On 03/10/2014 10:18 a.m., Vittorio Romeo wrote:
>>
>> (Sorry for the double post, I misclicked.)
>>
>> |
>> structMultiDimArray
>> {
>> auto&operator[](std::size_t mX,std::size_t mY)// currently not valid
>> {
>> // ...
>> }
>> };
>>
>> MultiDimArraymda;
>> mda[1,5]=10;
>> |
>>
>> I agree with this suggestion, it would be a nice addition to the language.
>
>
> This would be inconsistent with the way builtin arrays work.

And what would be the problem with that? People don't use the
subscript operator just for arrays. Whoever wants syntax consistency
with arrays can do that already returning a proxy.

> I would expect the syntax to call that overloaded subscript operator
> to be `mda[1][5]` instead. The other alternative, to change the way
> array indexing works, would be a breaking change and a needless
> incompatibility with C, so I think it would have a much lesser change
> of success.

That would be even worse because we would have two ways to
accomplish the same syntax. And having multiple arguments inside
the subscript operator would be *very* useful for EDSLs.

[snip]

> Regards,
> --
> Agustín K-ballo Bergé.-
> http://talesofcpp.fusionfenix.com

Best regards,
--
Felipe Magno de Almeida

Agustín K-ballo Bergé

unread,
Oct 3, 2014, 10:43:33 AM10/3/14
to std-pr...@isocpp.org
On 03/10/2014 11:23 a.m., Felipe Magno de Almeida wrote:
> Hello,
>
> On Fri, Oct 3, 2014 at 11:07 AM, Agustín K-ballo Bergé
> <kaba...@hotmail.com> wrote:
>> On 03/10/2014 10:18 a.m., Vittorio Romeo wrote:
>>>
>>> (Sorry for the double post, I misclicked.)
>>>
>>> |
>>> structMultiDimArray
>>> {
>>> auto&operator[](std::size_t mX,std::size_t mY)// currently not valid
>>> {
>>> // ...
>>> }
>>> };
>>>
>>> MultiDimArraymda;
>>> mda[1,5]=10;
>>> |
>>>
>>> I agree with this suggestion, it would be a nice addition to the language.
>>
>>
>> This would be inconsistent with the way builtin arrays work.
>
> And what would be the problem with that? People don't use the
> subscript operator just for arrays. Whoever wants syntax consistency
> with arrays can do that already returning a proxy.

Teachability (new gotchas).

>> I would expect the syntax to call that overloaded subscript operator
>> to be `mda[1][5]` instead. The other alternative, to change the way
>> array indexing works, would be a breaking change and a needless
>> incompatibility with C, so I think it would have a much lesser change
>> of success.
>
> That would be even worse because we would have two ways to
> accomplish the same syntax.

We already have lots of ways of accomplishing the same syntax (and not
two are exactly the same). If, on the other hand, you are referring to
more than one syntax with the same effect (array[1][5] and array[1,5]),
I agree, I am not suggesting that.

> And having multiple arguments inside
> the subscript operator would be *very* useful for EDSLs.

I cannot take this argument seriously. People writing EDSLs better know
what they are dealing with, users of the subscript operator need not to.
I don't think it would be reasonable to complicate the language for
everyone for no apparent benefit other than simplifying an already
complex use case (that would remain complex) for a minority.

Douglas Boffey

unread,
Oct 3, 2014, 10:49:03 AM10/3/14
to std-pr...@isocpp.org, daryl.va...@maptek.com.au
This would be a good proposal if it weren’t for the poor comma semantics inherited from C (and probably from its predecessors—I don’t know B or BCPL, so I cannot tell).

Given, as has already been mentioned, that this proposal would be a breaking proposal, I don’t believe that it would have a chance of being accepted;)

Thiago Macieira

unread,
Oct 3, 2014, 10:50:14 AM10/3/14
to std-pr...@isocpp.org
On Friday 03 October 2014 11:07:12 Agustín K-ballo Bergé wrote:
> Until a proposal of the sort makes it into the language, consider the
> following alternative:
>
> struct mda_index { std::size_t x; std::size_t y; };
>
> struct multi_dim_array {
> auto& operator[](mda_index i) const { /*...*/ }
> };
>
> multi_dim_array mda;
> mda[{1, 5}] = 10;

Simpler: use operator().
--
Thiago Macieira - thiago (AT) macieira.info - thiago (AT) kde.org
Software Architect - Intel Open Source Technology Center
PGP/GPG: 0x6EF45358; fingerprint:
E067 918B B660 DBD1 105C 966C 33F5 F005 6EF4 5358

Matthew Woehlke

unread,
Oct 3, 2014, 11:18:20 AM10/3/14
to std-pr...@isocpp.org
On 2014-10-03 10:07, Agustín K-ballo Bergé wrote:
> Until a proposal of the sort makes it into the language, consider the
> following alternative:
>
> struct mda_index { std::size_t x; std::size_t y; };

Is this even necessary? Or could you just use an initializer_list? Or
maybe std::array?

> struct multi_dim_array {
> auto& operator[](mda_index i) const { /*...*/ }
> };
>
> multi_dim_array mda;
> mda[{1, 5}] = 10;

--
Matthew

Klaim - Joël Lamotte

unread,
Oct 3, 2014, 2:07:13 PM10/3/14
to std-pr...@isocpp.org
I think this idea needs a demonstrative (aka real-world) use-case.
Otherwise, using the call operator seems enough to me.

David Krauss

unread,
Oct 3, 2014, 5:18:04 PM10/3/14
to std-pr...@isocpp.org

On 2014–10–03, at 10:49 PM, Douglas Boffey <douglas...@gmail.com> wrote:

Given, as has already been mentioned, that this proposal would be a breaking proposal, I don’t believe that it would have a chance of being accepted;)

I described a non-breaking strategy in the third post.

By the way, this is EWG 88.

Myriachan

unread,
Oct 4, 2014, 12:18:29 AM10/4/14
to std-pr...@isocpp.org

Is there a reason why keeping existing multidimensional element access syntax would be a problem?

template <typename T, std::size_t X, std::size_t Y>
class MyArray
{
public:
   
inline T &operator [](std::size_t x, std::size_t y)
   
{
       
return m_array[(x * Y) + y];
   
}
private:
    T m_array
[X * Y];
};

int main()
{
   
MyArray<int, 4, 9> array;
    array
[2][6] = 5;
   
return 0;
}

This could even be extended to variable arguments.  I mean, you could even define the syntax as being a std::tuple move chain.

But you could also just implement this as objects that return from operator [].

Melissa

David Krauss

unread,
Oct 4, 2014, 1:28:30 AM10/4/14
to std-pr...@isocpp.org

On 2014–10–04, at 12:18 PM, Myriachan <myri...@gmail.com> wrote:

On Friday, October 3, 2014 2:18:04 PM UTC-7, David Krauss wrote:
On 2014–10–03, at 10:49 PM, Douglas Boffey <douglas...@gmail.com> wrote:
Given, as has already been mentioned, that this proposal would be a breaking proposal, I don’t believe that it would have a chance of being accepted;)
I described a non-breaking strategy in the third post.

By the way, this is EWG 88.


Is there a reason why keeping existing multidimensional element access syntax would be a problem?

I guess that could work, using a process akin to the drill-down behavior of operator->. If the next [expr] wouldn’t work as a separate operator, expr gets added to the overload arguments. However, it would be very tricky, because a pointer is allowed to appear inside the brackets when the LHS (outside the brackets) is convertible to integer type.

daryl.va...@maptek.com.au

unread,
Oct 4, 2014, 2:39:42 AM10/4/14
to std-pr...@isocpp.org, daryl.va...@maptek.com.au
Yes, that's exactly what I want.

Bengt Gustafsson

unread,
Oct 4, 2014, 4:39:49 AM10/4/14
to std-pr...@isocpp.org
There is no particular problem with using () instead of [] for multi-dimensional access except that the convention in C++ seems to be that () indicates function invokation whereas [] indicates array access. This comes from C but has been augmented in C++ with operator() and operator[] overloading respectively. Forcing the use of () for array access because of a wart inherited from C does not seem like a good decision to me.

I agree with David that there is no code breaking issue using his proposed parsing rule.

However when reading EWG88 it does not discuss this parsing rule but instead they discuss whether there is enough code that actually uses a comma inside a [] to prevent allowing multiple arguments. Given the risk aversive history of the committe it is likely that the suggestion will be turned down on these grounds. Adding Davids parsing rule
to the proposal could thereby be worthwhile, as it would significantly increase the chances of getting the proposal adopted, I think.

Looking at plain "C" arrays I can not see anything that prevents the same rule to be used to allow multi-dimensional arrays using comma separated dimension expressions in the declaration and comma separated expressions at usage. There are however a few issues:

- How about the unknown size case? Should this be allowed, and if so with what syntax?

- Should it be possible to get a row/column out of the array using an under-defined operator? Or is this reserved for the current N-d arrays with separate [] for each dimension?

- Would it be a good idea to introduce a way to indicate which way the storage is indexed (row/column major). I have no idea on syntax for this but I know there have been numerous requests.

(Note that these points are for C arrays only, they will all be quite easy to accomplish for classes with [] overloads).
Reply all
Reply to author
Forward
0 new messages