views:

131

answers:

6

Hello,

I want to call a specific operator of specific base class of some class. For simple functions it's easy: I just write SpecificBaseClass::function( args );. How should I implement the same for operators without casting trickery?

Isolated problem:

 class A
 {
 public:
     A operator+( const A &other ) const {...}
 };

 class B : public A
 {
 public:
     B operator+( const B & other ) const {...}

 };

 ...
  B a, b;
  B c = A::operator+( a, b ); //how this should be implemented? I get an error
 ...

I get the following error on GCC4.5.1

error: no matching function for call to ‘A::operator+(B&, B&)’
note: candidate is: A A::operator+(const A&) const

Thanks!

EDIT improved the example to better illustrate the problem

+2  A: 

Try with:

a.operator+(b);
Matias Valdenegro
buratinas
+1  A: 

Can't you just say

c = b + a;
Faheem
You are assuming the + operator is symmetric for the class A. Though a good coding guide would suggest this it is not a requirement of the language.
Martin York
+7  A: 

The operator is a nonstatic member function, so you could use

a.A::operator+( b )

However, for another class that defines operator+ as a static member function, what you tried would be correct. And a third class might make it a free function (arguably the best way), so B::operator+(a,b) and a.operator+(b) would both be incorrect and operator+(a,b) would be right.

Generally it's best just to use operator syntax a+b unless you know exactly what class it is, and that its implementation will never change. In a template context, writing a+b is a must, and it's essentially impossible to take the address of the overload (the only task that requires naming it) without a lot of work.

In your context (a comment to another answer mentions templates), the best solution is

c = static_cast< A const & >( a ) + static_cast< A const & >( b );

… the problem is solved by slicing the types to reflect the subproblem, not precisely naming the function you want.

Potatoswatter
+1  A: 

Why not:

B c = a + b;
Because he wants to use `A`'s implementation of `operator+`, but this will use `B`'s implementation of `operator+`.
dreamlax
+1  A: 

The syntax of specifying a function as

<Class>::<Method>

is used when Method() is a static method in Class. If Method() is a instance method, then the invocation is on a class object.

Class classObject;
classObject.Method()

In this particular case, the declaration and usage of the operator+() method does not match.

So, one approach would be to make the operator+() method static. But, I think, operator methods can only be non-static member function or non-member function.

With all these knowledge, here is a full illustrative program.

#include <cassert>

struct B {
    int num_;

    B(int num) : num_( num ) {
    }

    static B add( const B & b1, const B & b2 ) {
        return B( b1.num_ + b2.num_ );
    }

    B operator+( const B & rhs ) {
        return B( num_ + rhs.num_ );
    }
};

int main() {
    B a(2), b(3);

    B c = B::add( a, b );
    assert( c.num_ == 5 );

    B d = a + b;
    assert( d.num_ == 5 );
}

The add() function is for example only, don't do it though.

ArunSaha
+1  A: 

There are two notions in C++: one is operator, and the other is operator-function. Operator informally is what is broadly called a built-in operator. You cannot call them in functional notation. Operator-function is what is called an overloaded operator which you can call as already is seen from many answers: that is, if @ is a member binary operator of class A, then someObjectOfTypeA.operarot@(someOtherObject), or if it is a freestanding function, then like operator@ (object1, object2)

Armen Tsirunyan