Discussion:
A postincrement operator
(too old to reply)
Vladimir Grigoriev
2009-12-22 15:58:49 UTC
Permalink
Let consider the code

struct A

{

};

struct B: public A

{

B() {}

B( const A &rhs ){}

B & operator ++()

{

return ( *this );

}

};



const B operator ++( B &lhs, int )

{

++lhs;

return ( B() );

}

int _tmain(int argc, _TCHAR* argv[])

{

A a;

a++;

}



Why does the compiler issue the error

error C2678: binary '++' : no operator found which takes a left-hand operand
of type 'A' (or there is no acceptable conversion)

could be 'const B operator ++(B &,int)'
while trying to match the argument list '(A, int)'



Vladimir Grigoriev
Igor Tandetnik
2009-12-22 16:11:10 UTC
Permalink
Post by Vladimir Grigoriev
struct B: public A
{
B( const A &rhs ){}
};
const B operator ++( B &lhs, int );
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a++;
}
Why does the compiler issue the error
error C2678: binary '++' : no operator found which takes a left-hand
operand of type 'A' (or there is no acceptable conversion)
You probably expect ::operator++(B(a), 0) to be called. However, a temporary can't bind to a non-const reference.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Vladimir Grigoriev
2009-12-22 16:24:10 UTC
Permalink
Thanks, Igor.

So, it seems that the operator ++( T &, int ) is the only operator that does
not allow conversion from a base class to a derived class with using the
corresponding constructor.

Vladimir Grigoriev
Post by Vladimir Grigoriev
struct B: public A
{
B( const A &rhs ){}
};
const B operator ++( B &lhs, int );
int _tmain(int argc, _TCHAR* argv[])
{
A a;
a++;
}
Why does the compiler issue the error
error C2678: binary '++' : no operator found which takes a left-hand
operand of type 'A' (or there is no acceptable conversion)
You probably expect ::operator++(B(a), 0) to be called. However, a temporary
can't bind to a non-const reference.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily
a good idea. It is hard to be sure where they are going to land, and it
could be dangerous sitting under them as they fly overhead. -- RFC 1925
Igor Tandetnik
2009-12-22 16:56:17 UTC
Permalink
Post by Vladimir Grigoriev
So, it seems that the operator ++( T &, int ) is the only operator
that does not allow conversion from a base class to a derived class
with using the corresponding constructor.
I don't understand this claim. operator++ is a function like any other. If you had

void f(B&);

you wouldn't be able to call f(a) either (with language extensions disabled).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Vladimir Grigoriev
2009-12-22 17:54:29 UTC
Permalink
Yes, it is a function, but it does not allow using a base class object even
if there is a conversion from a base class object to a derived class object.
With other operators which are written as a global function there is always
a problem how to prevent using a base class object in a operator.

Vladimir Grigoriev
Post by Vladimir Grigoriev
So, it seems that the operator ++( T &, int ) is the only operator
that does not allow conversion from a base class to a derived class
with using the corresponding constructor.
I don't understand this claim. operator++ is a function like any other. If
you had

void f(B&);

you wouldn't be able to call f(a) either (with language extensions
disabled).
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily
a good idea. It is hard to be sure where they are going to land, and it
could be dangerous sitting under them as they fly overhead. -- RFC 1925
Igor Tandetnik
2009-12-22 18:04:46 UTC
Permalink
Post by Vladimir Grigoriev
Yes, it is a function, but it does not allow using a base class
object even if there is a conversion from a base class object to a
derived class object.
The conversion produces a temporary. A temporary cannot be passed to a parameter of type reference-to-non-const. Your function takes just such a parameter. The fact that the function is called 'operator++' and not 'f' is irrelevant.
Post by Vladimir Grigoriev
With other operators which are written as a
global function there is always a problem how to prevent using a base
class object in a operator.
I suppose those other operators don't take non-const references as parameters.

Why do you want a constructor for a derived class from a base class in the first place? This doesn't seem to make much sense. Is it purely for academical interest, or are you trying to solve an actual problem this way?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Vladimir Grigoriev
2009-12-22 18:15:51 UTC
Permalink
The question is that almost all other operators which are defined as global
functions usually have parameters as const reference. And only this operator
has a non const reference.

Vladimir Grigoriev
Post by Vladimir Grigoriev
Yes, it is a function, but it does not allow using a base class
object even if there is a conversion from a base class object to a
derived class object.
The conversion produces a temporary. A temporary cannot be passed to a
parameter of type reference-to-non-const. Your function takes just such a
parameter. The fact that the function is called 'operator++' and not 'f' is
irrelevant.
Post by Vladimir Grigoriev
With other operators which are written as a
global function there is always a problem how to prevent using a base
class object in a operator.
I suppose those other operators don't take non-const references as
parameters.

Why do you want a constructor for a derived class from a base class in the
first place? This doesn't seem to make much sense. Is it purely for
academical interest, or are you trying to solve an actual problem this way?
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily
a good idea. It is hard to be sure where they are going to land, and it
could be dangerous sitting under them as they fly overhead. -- RFC 1925
Igor Tandetnik
2009-12-22 18:31:28 UTC
Permalink
Post by Vladimir Grigoriev
The question is that almost all other operators which are defined as
global functions usually have parameters as const reference. And only
this operator has a non const reference.
Well, you could write it to take a const reference. Would make about as much sense as passing a temporary to it, but it would in fact compile.

You use increment mostly for the sake of its side effect on the operand. That's why it usually takes non-const reference - so it could modify its operand. That's also why it doesn't make sense to pass a temporary to it - it'll modify the temporary, which will soon die anyway, and the original object will remain unchanged.
--
With best wishes,
Igor Tandetnik

With sufficient thrust, pigs fly just fine. However, this is not necessarily a good idea. It is hard to be sure where they are going to land, and it could be dangerous sitting under them as they fly overhead. -- RFC 1925
Loading...