Redefining operators in C++

B

bberu

Hi,

I know it is possible to refine operators (like +, -, * or /) on classes.
But is it possible on simple types ?
ex :
If I have a type like :
typedef int vector[100]
is it possible to redefine a + operator on the vetor type ?

Thanks !
Bruno
 
K

Karl Heinz Buchegger

bberu said:
Hi,

I know it is possible to refine operators (like +, -, * or /) on classes.
But is it possible on simple types ?
ex :
If I have a type like :
typedef int vector[100]
is it possible to redefine a + operator on the vetor type ?

vector is not a type.
vector is of type: array[100] of int

And no. It is not possible to define operators for the built in types.
 
I

Ivan Vecerina

Karl Heinz Buchegger said:
bberu said:
I know it is possible to refine operators (like +, -, * or /) on classes.
But is it possible on simple types ?
ex :
If I have a type like :
typedef int vector[100]
is it possible to redefine a + operator on the vetor type ?

vector is not a type.
vector is of type: array[100] of int

vector is indeed the name of a type (although a poorly chosen one).
And no. It is not possible to define operators for the built in types.

But the question was not about built-in types.

You can actually overload operators on some simple types such as enum:

enum SimpleType { stA, stB, stC };

SimpleType& operator++(SimpleType& a) {
if(a>=stC) a = stA; else a = static_cast<SimpleType>(a+1);
return a;
}


However, while functions can be overloaded on array parameters,
overloaded operators need to have at least one parameter of
a user-defined type:

typedef int vec3[3];

void add( vec3& a, vec3 const& b ) // ok, fully valid
{
a[0]+=b[0]; a[1]+=b[1]; a[2]+=b[2];
}

void operator++( vec3& a ) // ERROR - op overload requires UDT
{
a[0]+=1; a[1]+=1; a[2]+=1;
}


Anyway, array types have many caveats and limitations
(e.g. implicit conversion to pointers;
cannot be used as function return value).

It is much safer and easier to use a struct wrapping
the fixed-size array:
struct vec100
{
int m[100];
};
All operators can then be overloaded . By adding operator[]
members, you can also support the same syntax as for a
built-in array (and have the possibility to add bounds checks).

Boost and most likely the next version of the standard library
also include a template class that automates this process:
typedef array<int,100> vec100;


Cheers,
Ivan
 
R

Ron Natalie

Ivan said:
But the question was not about built-in types.

You can actually overload operators on some simple types such as enum:

enum SimpleType { stA, stB, stC };

To overload an operator, one operand must be of class or enum type.
Enum is NOT a simple type.
However, while functions can be overloaded on array parameters,

Nope. Any array in a function argument is converted to pointer to
the element type for the purposes of overloading.
void add( vec3& a, vec3 const& b ) // ok, fully valid

and identical to:
void add(int*&, int*const& )
for overloading purposes. This is an important distinction as:
typedef int vec4[4];
void add(vec4, vec4);
void add(vec3, vec3);
yield the same signature and make the program ill-formed.
 
S

Swampmonster

I know it is possible to refine operators (like +, -, * or /) on classes.
But is it possible on simple types ?
ex :
If I have a type like :
typedef int vector[100]
is it possible to redefine a + operator on the vetor type ?

Hi!

vector is NOT a type. vector is a type-alias for "int [100]"
So no, you can't overload operators, since at least one argument of on
overloaded operator needs to be of class-type (user defined type).
You might do something like:


struct my_vector
// don't just use "vector" because everybode who reads it will
// immediately think so std::vector<> which is a completely different
// thing
{
int elements[100];
};

Then you can overload any operator + or whatever you like.
If you want you can overload operator [] to enable direct access to the
elements. You might even check the index inside that operator, which is
a nice thing to have, at least for debug builds.
Bye,
'monster
 
I

Ivan Vecerina

Ron Natalie said:
To overload an operator, one operand must be of class or enum type.
Enum is NOT a simple type.

Does your claim have any basis in the C++ standard?
From a naive perspective, an enum is pretty much a simple type.
From a formal perspective, SimpleType would qualify as
a "Simple type specifier"(§7.1.5).
But the real point is that I don't think that the unspecific
wording should be interepreted to the detriment of the OP.
Nope. Any array in a function argument is converted to pointer to
the element type for the purposes of overloading.

Not if this array is passed by reference, as in the example
I provided.
See §8.3.5: the decay of array to pointer applies if the
parameter is of type "array of T". This does not include
parameters that would be of type "reference to array of T".
and identical to:
void add(int*&, int*const& )
for overloading purposes.

Not true - a reference to a pointer is not equivalent to
a reference to an array.
Did you try to compile the sample code I had provided ?

This is an important distinction as:
typedef int vec4[4];
void add(vec4, vec4);
void add(vec3, vec3);
yield the same signature and make the program ill-formed.

Yes - in your modified example.
But the following functions have distinct signatures:
void add(vec4&, vec4&);
void add(vec3&, vec3&);

And we naturally agree on that, I believe.


Regards,
Ivan
 
R

Ron Natalie

Ivan said:
Does your claim have any basis in the C++ standard?
From a naive perspective, an enum is pretty much a simple type.

Certainly, or I would not have made it. 3.9.2 defines enum
as a compound type.
From a formal perspective, SimpleType would qualify as
a "Simple type specifier"(§7.1.5).

A simple type specifier is just one that can be expressed as
a single word. It can be anything from a class to a int.
There are fundamental types (the proper antonym to compound
type) that are not expressed with simple type specifiers:
unsigned short
is not.
std::exception
is.
 
I

Ivan Vecerina

Ron Natalie said:
Certainly, or I would not have made it. 3.9.2 defines enum
as a compound type.

So let's call it a simple compound type ;)
I just disagree that "simple" had to imply "fundamental"
in the context of the OP.

Kind regards,
Ivan
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,754
Messages
2,569,528
Members
45,000
Latest member
MurrayKeync

Latest Threads

Top