Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Operator overloading

56 views
Skip to first unread message

jacobnavia

unread,
Jun 27, 2020, 2:46:44 AM6/27/20
to
Hi

I have implemented operator overloading in the context of the C
language, and I have a quetstion concerning the behavior of C++ with the
operator [ ] (indexing) and multi-dimensional arrays.

Supposing I have a 3 dimensional array of some type T.

T table[2][5][2]; // 2 planes, 5 rows, 2 columns

How do you overload the access to T?

Thanks in advance.

jacob

Bonita Montero

unread,
Jun 27, 2020, 2:53:08 AM6/27/20
to
Impossible !
You have to have an object at each level where you apply the
[]-operator. If you't declare a multidimensional vector, you'd
write this:

#include <vector>

using namespace std;

int main()
{
vector<vector<vector<int>>> threeDimensional;
// creates the the first element of the first, second and
// third dimension (compile with C++17 !)
threeDimensional.emplace_back().emplace_back().emplace_back();
threeDimensional[0][0][0] = 0;
}

Bonita Montero

unread,
Jun 27, 2020, 3:11:37 AM6/27/20
to
Maybe this is a more proper example:

#include <vector>
#include <iostream>

using namespace std;

int main()
{
vector<vector<vector<size_t>>> vvvi;
vvvi.reserve( 10 );
for( size_t i = 0; i != 10; ++i )
{
vector<vector<size_t>> &vvi = vvvi.emplace_back();
vvi.reserve( 10 );
for( size_t j = 0; j != 10; ++j )
{
vector<size_t> &vi = vvi.emplace_back();
vi.resize( 10 );
for( size_t k = 0; k != 10; ++k )
vi[k] = i << 16 | j << 8 | k;
}
}
size_t sum = 0;
for( size_t i = 0; i != vvvi.size(); ++i )
for( size_t j = 0; j != vvvi[i].size(); ++j )
for( size_t k = 0; k != vvvi[i][j].size(); ++k )
sum += vvvi[i][j][k];
cout << "sum: " << sum << endl;
}

jacobnavia

unread,
Jun 27, 2020, 4:23:09 AM6/27/20
to
Sorry but I got
acob@rock64:~/lcc/book/test$ g++ tidx.cpp
tidx.cpp: In function ‘int main()’:
tidx.cpp:12:56: error: invalid initialization of non-const reference of
type ‘std::vector<std::vector<long unsigned int> >&’ from an rvalue of
type ‘void’
vector<vector<size_t>> &vvi = vvvi.emplace_back();
~~~~~~~~~~~~~~~~~^~
tidx.cpp:16:50: error: invalid initialization of non-const reference of
type ‘std::vector<long unsigned int>&’ from an rvalue of type ‘void’
vector<size_t> &vi = vvi.emplace_back();
~~~~~~~~~~~~~~~~^~
jacob@rock64:~/lcc/book/test$

Must be a problem somwhere but my C++ is too weak to figure it out.

Anyway thanks for your input.

Ian Collins

unread,
Jun 27, 2020, 4:49:40 AM6/27/20
to
Some thing like:

#include <array>

using Column = std::array<int,2>;
using Row = std::array<Column,5>;
using Plane = std::array<Row,2>;

int main()
{
Plane plane;
plane[1][2][1] = 0;

Column col {1,2};
plane[1][1] = col;
}

?

--
Ian.

Bonita Montero

unread,
Jun 27, 2020, 4:51:19 AM6/27/20
to
> type ‘void’
>          vector<vector<size_t>> &vvi = vvvi.emplace_back();
>                                        ~~~~~~~~~~~~~~~~~^~
> tidx.cpp:16:50: error: invalid initialization of non-const reference of
> type ‘std::vector<long unsigned int>&’ from an rvalue of type ‘void’
>              vector<size_t> &vi = vvi.emplace_back();
>                                   ~~~~~~~~~~~~~~~~^~
> jacob@rock64:~/lcc/book/test$
> Must be a problem somwhere but my C++ is too weak to figure it out.
> Anyway thanks for your input.

C++ supports emplace_back with a reference-return since C++17.

jacobnavia

unread,
Jun 27, 2020, 5:11:59 AM6/27/20
to
I used:
g++ -std=c++17 tidx.cpp

The same error...

Melzzzzz

unread,
Jun 27, 2020, 5:32:13 AM6/27/20
to
You don't. Operator [] is single function. You call another [] on result
of previous [], and again.

>
> Thanks in advance.
>
> jacob


--
current job title: senior software engineer
skills: c++,c,rust,go,nim,haskell...

press any key to continue or any other to quit...
U ničemu ja ne uživam kao u svom statusu INVALIDA -- Zli Zec
Svi smo svedoci - oko 3 godine intenzivne propagande je dovoljno da jedan narod poludi -- Zli Zec
Na divljem zapadu i nije bilo tako puno nasilja, upravo zato jer su svi
bili naoruzani. -- Mladen Gogala

Bonita Montero

unread,
Jun 27, 2020, 5:42:42 AM6/27/20
to
>> C++ supports emplace_back with a reference-return since C++17.

> I used:
> g++ -std=c++17 tidx.cpp

Maybe an outdated standard-libary. Look here:
https://en.cppreference.com/w/cpp/container/vector/emplace_back
Since C++17 the STL shoud return a reference.

alelvb

unread,
Jun 27, 2020, 7:29:16 AM6/27/20
to
Il 27/06/20 08:46, jacobnavia ha scritto:
I'm playing with 2 dimensional std::vectors, but you can extend
this for arrays with a bigger number of dimensions.

my code is maybe not the most orthodox but it works:

//******** cut here *********

#include <initializer_list>
#include <iostream>
#include <vector>

using uInt = long long unsigned int;

template <typename T>
class Matrix
{
public:
/* ===================
* the constructors
* =================== */

Matrix(std::initializer_list<std::initializer_list<T>> lil);
Matrix(const Matrix<T>& m) = default;
Matrix(Matrix<T>&& r) = default;
Matrix(uInt r, uInt c);

/* ===================
* member functions
* =================== */

uInt rows() const { return row; }
uInt columns() const { return col; }

std::vector<T> operator[] (const uInt r) const { return data.at(r); }
std::vector<T>& operator[] (const uInt r) { return data.at(r); }

~Matrix<T>() = default;

/* ===================
* the '<<' operator
* =================== */

friend std::ostream& operator<< (std::ostream& out, const Matrix<T>& m)
{
for(uInt i=0; i != m.rows(); ++i)
{
for(uInt j=0; j != m.columns(); ++j)
{
out << m.data[i][j] << ' ';
}
out << '\n';
}
return out;
}

/* ===================
* data members
* =================== */

private:
std::vector<std::vector<T>> data;
uInt row;
uInt col;
};


/* ===================
* constructor implem
* =================== */

template <typename T>
Matrix<T>::Matrix(std::initializer_list<std::initializer_list<T>> lil)
{
uInt r=0, count=0, maxcols=0;

for(auto y : lil)
{
++r;
std::vector<T> v;
data.push_back(v);

for(auto x : y)
{
++count;
}

if(count > maxcols)
maxcols = count;

count=0;
}

row = r;
col = maxcols;

// initialization
int i=0;
for(auto y : lil)
{
for(auto x : y)
{
data.at(i).push_back(x);
}
++i;
}
}

/* ===================
* the main function
* =================== */

int main()
{
Matrix<double> m {{0,1,2},{0,1,1},{1,0,1}};

std::cout << m << '\n';
}

Alf P. Steinbach

unread,
Jun 27, 2020, 10:52:00 AM6/27/20
to
On 27.06.2020 08:46, jacobnavia wrote:
> Hi
>
> I have implemented operator overloading in the context of the C
> language,

I don't quite see what that could be about.

Some macro-based support for function overloading was added in C11, but
is that what you have leveraged?

Or what?


> and I have a quetstion concerning the behavior of C++ with the
> operator [ ] (indexing) and multi-dimensional arrays.
>
> Supposing I have a 3 dimensional array of some type T.
>
> T table[2][5][2];  // 2 planes, 5 rows, 2 columns
>
> How do you overload the access to T?

Generally you don't, because operator[] only takes a single argument.

That single argument can of course be a struct with two or more indices,
and/or the indexing result can be something that can further indexed.
The struct thing is just impractical notation. The indexable result
thing can be as simple as returning a pointer, but in this case it
exposes the array internals. Alternatively the result can be a proxy
object but that's both complex and bug prone and possibly inefficient.

So, for general indexing of a multidimensional array it's common to use
either the function call operator `operator()`, and/or named indexing
functions with names such as `at` or `item`.

Example:


-----------------------------------------------------------------------
#include <stddef.h> // ptrdiff_t

#include <array> // std::array
#include <utility> // std::enable_if, std::move
#include <vector> // std::vector

namespace my {
using
std::array,
std::enable_if_t, std::move,
std::vector;

using Size = ptrdiff_t;
using Index = ptrdiff_t;

template< int arity_param, class Value_param >
class Multidimensional_array_
{
public:
static constexpr int arity = arity_param;
using Value = Value_param;

static_assert( arity > 0 );

private:
vector<Value> m_items;
array<Size, arity> m_sizes;

template< class... Indices >
auto index_for( const Indices... index_args )
-> Index
{
const array<Index, arity> indices = {index_args...};

Size weight = 1;
Index result = 0;
for( int i = 0; i < arity; ++i ) {
result += indices[i]*weight;
weight *= m_sizes[i];
}
return result;
}

public:
// The first size is "innermost", opposite of a raw
multidimensional array.
template<
class... Size_types,
class = enable_if_t< sizeof...( Size_types ) == arity >
>
Multidimensional_array_( const Size_types... sizes ):
m_items( (1 * ... * sizes) ),
m_sizes{ sizes... }
{}

template<
class... Index_types,
class = enable_if_t< sizeof...( Index_types ) == arity >
>
auto operator()( const Index_types... indices ) const
-> const Value&
{ return m_items[index_for( indices... )]; }

template<
class... Index_types,
class = enable_if_t< sizeof...( Index_types ) == arity >
>
auto operator()( const Index_types... indices )
-> Value&
{ return m_items[index_for( indices... )]; }

Multidimensional_array_( const Multidimensional_array_& other )
= default;
Multidimensional_array_( Multidimensional_array_&& other ) =
default;

auto size( const int dimension ) const
-> Size
{ return m_sizes[dimension]; }
};

template< class Value_param >
using Array_2d = Multidimensional_array_<2, Value_param>;

template< class Value_param >
using Array_3d = Multidimensional_array_<3, Value_param>;
} // namespace my

#include <iomanip>
#include <iostream>
using
std::setw,
std::cout, std::endl;

auto main()
-> int
{
auto box = my::Array_3d<double>( 2, 5, 2 );

for( int z = 0; z < box.size( 2 ); ++z ) {
for( int y = 0; y < box.size( 1 ); ++y ) {
for( int x = 0; x < box.size( 0 ); ++x ) {
box( x, y, z ) = 100*(z + 1) + 10*(y + 1) + (x + 1);
}
}
}

for( int z = 0; z < box.size( 2 ); ++z ) {
for( int y = 0; y < box.size( 1 ); ++y ) {
for( int x = 0; x < box.size( 0 ); ++x ) {
cout << setw( 4 ) << box( x, y, z );
}
cout << endl;
}
cout << endl;
}
}
-----------------------------------------------------------------------


- Alf

jacobnavia

unread,
Jun 27, 2020, 11:13:55 AM6/27/20
to
YES!
I compiled in my macintosh and it worked. Before I was compiling in an
arm. Apparently the library of the arm system is a bit old

Thanks

Juha Nieminen

unread,
Jun 27, 2020, 11:33:24 AM6/27/20
to
jacobnavia <ja...@jacob.remcomp.fr> wrote:
> I have implemented operator overloading in the context of the C
> language

What does that even mean?

Juha Nieminen

unread,
Jun 27, 2020, 11:36:47 AM6/27/20
to
Melzzzzz <Melz...@zzzzz.com> wrote:
> You don't. Operator [] is single function. You call another [] on result
> of previous [], and again.

I wonder if it would break anything if support for multidimensional
operator[] would be added. It could work simply like this:

class MyClass
{
public:
void operator[](std::size_t i1, std::size_t i2)
{
std::cout << "[" << i1 << "][" << i2 << "]\n";
}
};


void foo()
{
MyClass obj;
obj[10][20];
}

Why add this kind of support? Because it would significantly
simplify overloading multidimensional indexing.

David Brown

unread,
Jun 27, 2020, 12:28:34 PM6/27/20
to
There is, I believe, I move towards sane multi-dimensional indexing
support in C++, in the form "obj[10, 20]" - the use of the comma
operator is deprecated within array expressions in C++20. But it will
take many generations of C++ standards before such array expressions can
be used - backwards compatibility is a bugger when you have to keep
supporting language design mistakes. Personally, I think /all/ use of
the comma operator should have been deprecated.

Another way of making multi-dimensional arrays with nice indexing is to
overload the function call operator, so that you can write:

obj(10, 20)

jacobnavia

unread,
Jun 27, 2020, 12:34:36 PM6/27/20
to
Le 27/06/2020 à 16:51, Alf P. Steinbach a écrit :
> On 27.06.2020 08:46, jacobnavia wrote:
>> Hi
>>
>> I have implemented operator overloading in the context of the C language,
>
> I don't quite see what that could be about.
>
> Some macro-based support for function overloading was added in C11, but
> is that what you have leveraged?
>
> Or what?
>

I repeat. I am the developer of the lcc-win compiler system, and in that
compiler I have implemented operator overloading, roughly similar to c++
with some differences.
>
>> and I have a quetstion concerning the behavior of C++ with the
>> operator [ ] (indexing) and multi-dimensional arrays.
>>
>> Supposing I have a 3 dimensional array of some type T.
>>
>> T table[2][5][2];  // 2 planes, 5 rows, 2 columns
>>
>> How do you overload the access to T?
>
> Generally you don't, because operator[] only takes a single argument.
>

In my system you have the operator [ ] (accessing an array for reading)
and the operator [ ] = (accessing an array for writing)

The last one takes 3 arguments: the object, the index, and the value.

Now, I wanted to know how C++ manages multi-dimensional array access,
and apparently it doesn't. So I have no c++ compatibility problem since
there isn't anything there.

Thanks for your input.

I compiled your code and it runs ok, but I would like to keep the []
notation.

jacob

jacobnavia

unread,
Jun 27, 2020, 12:40:46 PM6/27/20
to
typedef struct { double real,double imag; } cmplx;

cmplx operator +(complx a,cmplx b) {
cmplx result;

result.real = a.real+b.real;
result.imag = a.imag+b.imag;
return result;
}

int main(void)
{
cmplx a,b={2,3},c={4,5};
c = a+b;
}

This compiles in the lcc-win compiler system. It is called "operator
overloading" and many languages support it like Fortran, c# and others.
It has been a standard feature of my compiler system since 2005.

Paavo Helde

unread,
Jun 27, 2020, 2:05:14 PM6/27/20
to
27.06.2020 19:28 David Brown kirjutas:

> There is, I believe, I move towards sane multi-dimensional indexing
> support in C++, in the form "obj[10, 20]" - the use of the comma
> operator is deprecated within array expressions in C++20. But it will
> take many generations of C++ standards before such array expressions can
> be used - backwards compatibility is a bugger when you have to keep
> supporting language design mistakes. Personally, I think /all/ use of
> the comma operator should have been deprecated.

The comma operator is essential for for. There are uncountably many for
loop expressions using the comma operator and it can be never deprecated
there.

For [] I agree: ',' does not mean comma operator inside (), [] should
behave the same, just for symmetry. For lambda [] this already works so.



Bonita Montero

unread,
Jun 27, 2020, 2:32:19 PM6/27/20
to
> typedef struct { double real,double imag; } cmplx;
> cmplx operator +(complx a,cmplx b) {
>     cmplx result;
>
>     result.real = a.real+b.real;
>     result.imag = a.imag+b.imag;
>     return result;
> }
> int main(void)
> {
>     cmplx a,b={2,3},c={4,5};
>     c = a+b;
> }
> This compiles in the lcc-win compiler system. It is called "operator
> overloading" and many languages support it like Fortran, c# and others.
> It has been a standard feature of my compiler system since 2005.

If you are not writing your own complex-class for educational purposes:
you can #include <complex> and thereby have a full blown complex-class
with all appropriate operators.

guinne...@gmail.com

unread,
Jun 27, 2020, 2:34:29 PM6/27/20
to
On Saturday, 27 June 2020 17:40:46 UTC+1, jacobnavia wrote:
> Le 27/06/2020 à 17:33, Juha Nieminen a écrit :
> > jacobnavia <ja...@jacob.remcomp.fr> wrote:
> >> I have implemented operator overloading in the context of the C
> >> language
> >
> > What does that even mean?
> >
>
> typedef struct { double real,double imag; } cmplx;
>
> cmplx operator +(complx a,cmplx b) {
> cmplx result;
>
> result.real = a.real+b.real;
> result.imag = a.imag+b.imag;
> return result;
> }
>
> int main(void)
> {
> cmplx a,b={2,3},c={4,5};
> c = a+b;
> }
>
> This compiles in the lcc-win compiler system.

Really? What meaning does lcc-win ascribe to this non-C code?

typedef struct { double real,double imag; } cmplx;

(C compilers complain about the word 'double' following the comma).

Are commas and semicolons interchangeable in struct definitions
when compiling under lcc-win?

David Brown

unread,
Jun 27, 2020, 3:36:39 PM6/27/20
to
On 27/06/2020 20:05, Paavo Helde wrote:
> 27.06.2020 19:28 David Brown kirjutas:
>
>> There is, I believe, I move towards sane multi-dimensional indexing
>> support in C++, in the form "obj[10, 20]" - the use of the comma
>> operator is deprecated within array expressions in C++20.  But it will
>> take many generations of C++ standards before such array expressions can
>> be used - backwards compatibility is a bugger when you have to keep
>> supporting language design mistakes.  Personally, I think /all/ use of
>> the comma operator should have been deprecated.
>
> The comma operator is essential for for. There are uncountably many for
> loop expressions using the comma operator and it can be never deprecated
> there.

It is not remotely "essential" - people write perfectly good, clear and
efficient "for" loops without the comma operator. But some people
/like/ to use the comma operator, and feel it makes their code
(especially "for" loops) better. Fair enough - it's a feature of the
language, and just one of many non-essential features that people use.

You are certainly right, however, that there is lots of existing code
with comma operators, which is why deprecating it (in any situation) is
something that will take time to be effective.

>
> For [] I agree: ',' does not mean comma operator inside (), [] should
> behave the same, just for symmetry. For lambda [] this already works so.
>

I think it would be more consistent to deprecate it in all places. But
I am fully aware that that is a personal opinion, and not one that is
likely to be implemented in practice.


Keith Thompson

unread,
Jun 27, 2020, 7:20:37 PM6/27/20
to
jacobnavia <ja...@jacob.remcomp.fr> writes:
> Le 27/06/2020 à 16:51, Alf P. Steinbach a écrit :
>> On 27.06.2020 08:46, jacobnavia wrote:
[...]
>>> Supposing I have a 3 dimensional array of some type T.
>>>
>>> T table[2][5][2];  // 2 planes, 5 rows, 2 columns
>>>
>>> How do you overload the access to T?
>>
>> Generally you don't, because operator[] only takes a single argument.
>
> In my system you have the operator [ ] (accessing an array for
> reading) and the operator [ ] = (accessing an array for writing)
>
> The last one takes 3 arguments: the object, the index, and the value.
>
> Now, I wanted to know how C++ manages multi-dimensional array access,
> and apparently it doesn't. So I have no c++ compatibility problem
> since there isn't anything there.

Neither C nor C++ supports multi-dimensional arrays as a distinct
concept.

In standard C, a multidimensional array is nothing more or less
than an array of arrays. You can also use table[2][5][2] notation
in contexts involving pointers rather than arrays.

C++ is pretty much the same, with the addition of operator
overloading. In C++, table[2][5][2] can be valid if each of
table[2][5], table[2], and table is of pointer type (possibly the
result of array-to-pointer conversion) or of some class type (which
includes struct or union type) with an appropriately overloaded
operator[].

--
Keith Thompson (The_Other_Keith) Keith.S.T...@gmail.com
Working, but not speaking, for Philips Healthcare
void Void(void) { Void(); } /* The recursive call of the void */

Ian Collins

unread,
Jun 27, 2020, 9:26:10 PM6/27/20
to
The biggest difference with C++ is that through operator overloading you
can copy from and assign to full elements (such as whole rows and
columns) of a multidimensional array. std::array is a very handy tool
to have.

--
Ian.

jacobnavia

unread,
Jun 28, 2020, 3:34:07 AM6/28/20
to
Yes, lcc-win supports the standard complex numbers. That was an
exemple of operator overloading though, I could have choosen anything
else but that was the first that came to mind. Maybe not a good exemple

David Brown

unread,
Jun 28, 2020, 4:15:03 AM6/28/20
to
Operator overloading is just one part of the mechanics that allow that.
I wonder if and how lcc can support something like that, without
(AFAIUI) classes, overloads of normal functions, constructors and
destructors?

jacobnavia

unread,
Jun 28, 2020, 5:47:23 AM6/28/20
to
Le 28/06/2020 à 10:14, David Brown a écrit :

>
> Operator overloading is just one part of the mechanics that allow that.
> I wonder if and how lcc can support something like that, without
> (AFAIUI) classes, overloads of normal functions, constructors and
> destructors?
>

1) No classes. Just structures and unions. No inheritance and no object
oriented programming support. You can (of course) do object oriented
programming in C as many frameworks available will prove.

2) Overloads of normal functions are also supported

int overloaded fn(int a); // 1
int overloaded fn(char *b); // 2

int main(void) {
fn("foo"); // 2
fn(45); // 1
}

3) No constructors nor destructors. This is C and you do it yourself.

Using operator overloading lcc-win supports many types of numbers:

bignums
big floats (448 bits precision)

You can define your own addition, etc for introducing clapped addition,
for instance.

Key is: Do not follow the C++ path. KEEP IT SIMPLE! but no simpler than
what is required. Operator overloading is very useful. It allows us to
use a known notation.

Noteworthy is that lcc-win supports operator [ ] reading from an array
and operator [ ] = assigning to an array element. This allows to
implement read only arrays


Ike Naar

unread,
Jun 28, 2020, 7:06:32 AM6/28/20
to
On 2020-06-27, jacobnavia <ja...@jacob.remcomp.fr> wrote:
> {
> cmplx a,b={2,3},c={4,5};
> c = a+b;

Did you mean

a = b+c;
?

Bart

unread,
Jun 28, 2020, 7:17:03 AM6/28/20
to
I'm about to implement operator overloading (not in a C-related language).

It doesn't need any such features, only a compiler directive to
associate a regular function with an operator and a set of operand
types. Suppose S and T are two user types on which you want to use
binary "+", then, using pseudo-C syntax:

S addS(S a, S b) {S c; ....; return c;}

T addT(T a, T b) {T c; ....; return c;}

#pragma setoverload "+"(S,S) addS
#pragma setoverload "+"(T,T) addT

S x,y,z;
z = x+y; // tranformed to z = addS(x,y)

If constructors and destructors are needed, then they will be needed
regardless of operator overloading. This is just so you can write x+y+z
instead of addS(x,addS(y,z)).


jacobnavia

unread,
Jun 28, 2020, 8:48:34 AM6/28/20
to
yes, just a stupid typo

thanks

Juha Nieminen

unread,
Jun 28, 2020, 11:42:45 AM6/28/20
to
David Brown <david...@hesbynett.no> wrote:
>> class MyClass
>> {
>> public:
>> void operator[](std::size_t i1, std::size_t i2)
>> {
>> std::cout << "[" << i1 << "][" << i2 << "]\n";
>> }
>> };
>>
>>
>> void foo()
>> {
>> MyClass obj;
>> obj[10][20];
>> }
>
> There is, I believe, I move towards sane multi-dimensional indexing
> support in C++, in the form "obj[10, 20]" - the use of the comma
> operator is deprecated within array expressions in C++20. But it will
> take many generations of C++ standards before such array expressions can
> be used - backwards compatibility is a bugger when you have to keep
> supporting language design mistakes. Personally, I think /all/ use of
> the comma operator should have been deprecated.

The advantage of my proposal above is that it would be fully
backwards-compatible with existing code, and there would be zero
need to deprecate or change anything in the current language
(with the exception of, rather obviously, that now operator[]()
can take more than one parameter, which is not a backwards
compatibility breaking change nor needs any deprecation of
anything.)

Of course not being a C++ standard expert or a compiler developer,
I don't know if it could perhaps cause some kind of ambiguity in
some situations, where the compiler cannot know if "obj[1][2]"
refers to one thing or another.

It could certainly be ostensibly problematic if the class has
an operator[]() taking one parameter and another taking two,
as the compiler wouldn't know which one the "obj[1][2]" should call.

jacobnavia

unread,
Jun 28, 2020, 4:32:22 PM6/28/20
to
Le 27/06/2020 à 17:36, Juha Nieminen a écrit :
> I wonder if it would break anything if support for multidimensional
> operator[] would be added. It could work simply like this:
>
> class MyClass
> {
> public:
> void operator[](std::size_t i1, std::size_t i2)
> {
> std::cout << "[" << i1 << "][" << i2 << "]\n";
> }
> };

I have been studying your proposal, and I have some questions:

1) In this example you are overloading the indexing operator for an
array of a specific size, that you enter in your overloading definition.

(If I understood correctly of course)

Now, in my implementation I was thinking about this operator for a
general object of a certain rank. Instead of specific table sizes you
would just give an integer RANK of the array being overloaded.

The advantages of this, is that you overload the indexing operator for
ALL arrays of a certain number of dimensions (its rank) instead of
having to overload each array of different sizes.

Practically you would want to overload all tables, and not only tables
of 2 by 5 and write another operator for tables of 2 by 7, say.

I thought that in overloading the operator you would overload by rank
like this

operator [2](T basetype, int idx1, int idx2) { ... }

Of course in C++ you don't pass the first argument (implicit this)
and the operator would be written

operator[2](int idx1,int idx2);

That would mean that ALL tables (rank 2) of that class would be
overloaded with the definition, not only tables of a specific size.

What do you think?

jacob


David Brown

unread,
Jun 29, 2020, 4:39:42 AM6/29/20
to
Oh, you can be confident that there would be ambiguity somewhere! The
way the language is defined, it is very difficult to change such details
of how operators work - the syntax, arity, associativity, etc., of the
operators is fixed. It would be nice if it were possible to change
these things, make a "**" power operator, or whatever, but we can't.
(Jacob can, of course, since his compiler is for his own extended C.)

It should not be too hard, however, to make a template for
multi-dimensional arrays that cooks down to a single function like that
for accessing the elements (in case you want a specialised access
function - perhaps for sparse arrays).

Bo Persson

unread,
Jun 29, 2020, 5:03:03 AM6/29/20
to
There is a formal proposal to allow a member operator[] to work the same
as an operator() member, especially regarding multiple parameters.

That would allow "multi-dimensional syntax" for user defined types,
without causing problems for existing code using built-in arrays.

https://wg21.link/P2128


Bo Persson
0 new messages