Как вызвать оператор как функцию в C ++ - PullRequest
11 голосов
/ 19 октября 2010

Я хочу вызвать определенный оператор определенного базового класса некоторого класса.Для простых функций это просто: я просто пишу SpecificBaseClass::function( args );.Как мне реализовать то же самое для операторов без приведения?

Изолированная проблема:

 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
 ...

Я получаю следующую ошибку от GCC4.5.1 :

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

Спасибо !

РЕДАКТИРОВАТЬ
Я улучшил пример, чтобы лучше проиллюстрировать проблему.

Ответы [ 6 ]

18 голосов
/ 19 октября 2010

Оператор является нестатической функцией-членом, поэтому вы можете использовать

a.A::operator+( b )

Однако для другого класса, который определяет operator+ как статическую функцию-член, то, что вы пробовали, будет правильным.А третий класс может сделать ее бесплатной функцией (возможно, лучшим способом), поэтому B::operator+(a,b) и a.operator+(b) будут неверными, а operator+(a,b) правильными.

Как правило, лучше всего использовать операторсинтаксис a+b, если вы точно не знаете, что это за класс, и что его реализация никогда не изменится.В контексте шаблона написание a+b является обязательным, и по существу невозможно получить адрес перегрузки (единственная задача, для которой требуется присвоение ему имени) без большой работы.

В вашем контексте (в комментарии к другому ответу упоминаются шаблоны), лучшим решением будет

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

… проблема решается путем разрезания типов в соответствии с подзадачей, а не с точным наименованием нужной функции.

4 голосов
/ 19 октября 2010

В C ++ есть два понятия: одно - оператор, а другое - оператор-функция.Оператор неофициально - это то, что широко называется встроенным оператором.Вы не можете назвать их в функциональной записи.Оператор-функция - это то, что называется перегруженным оператором, который вы можете вызывать, как уже было видно из многих ответов: то есть, если @ является двоичным оператором-членом класса A, то someObjectOfTypeA.operarot@(someOtherObject) или если это автономная функция,как operator@ (object1, object2)

4 голосов
/ 19 октября 2010

Синтаксис определения функции как

<Class>::<Method>

используется, когда Method() является статическим методом в Class.Если Method() является методом экземпляра, то вызов выполняется для объекта класса.

Class classObject;
classObject.Method()

В этом конкретном случае объявление и использование метода operator+() не совпадают.

Итак, одним из подходов было бы сделать метод operator+() static.Но, я думаю, operator методы могут быть только нестатическими функциями-членами или не-функциями-членами.

Со всеми этими знаниями, вот полная иллюстративная программа.

#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 );
}

Функция add() предназначена только для примера, но не делайте этого.

4 голосов
/ 19 октября 2010

Попробуйте с:

a.operator+(b);
1 голос
/ 19 октября 2010

Почему бы и нет:

B c = a + b;
1 голос
/ 19 октября 2010

Разве вы не можете просто сказать

c = b + a;
...