перегрузка оператора ‹‹

Код:

std::ostream& operator<<(std::ostream& os, const BmvMessage& bm);

Я не вижу ничего неправильного, но выдает следующую ошибку:

error: `std::ostream& BMV::BmvMessage::operator‹‹(std::ostream&, const BMV::BmvMessage&)' должен принимать ровно один аргумент.

Я не знаю, почему это происходит. Любые предложения приветствуются. Я делал это раньше и никогда не сталкивался с этой ошибкой. Я также проверил онлайн, и это выглядит так:

ostream& operator<< (ostream& out, char c );`

person CodersSC    schedule 16.11.2011    source источник
comment
Вы говорите о бесплатной функции или функции-члене?   -  person Kerrek SB    schedule 16.11.2011
comment
Err это ваш код объявления? если да, то можете ли вы показать класс?   -  person Ahmed Masud    schedule 16.11.2011
comment
оператор ostream&‹‹(ostream& os, const BmvMessage& bm); да вы видите что-то не так?   -  person CodersSC    schedule 16.11.2011
comment
@ShamariCampbell: Для справки в будущем: это было бы довольно важным фактом для включения в ваш вопрос!   -  person Kerrek SB    schedule 16.11.2011
comment
@Kerrek SB, да, извините, вы видите, почему отображается эта ошибка?   -  person CodersSC    schedule 16.11.2011
comment
Предоставьте полную минимальную программу. Полная программа — это та, которую мы можем скомпилировать точно так же, как и вы, и получить ту же ошибку, что и вы. Минимальная программа — это программа, в которой удалены все строки, не имеющие отношения к вашей проблеме. См. sscce.org, чтобы понять, почему это важно.   -  person Robᵩ    schedule 16.11.2011


Ответы (3)


Возьмите operator<< за пределы класса, сделав его свободной функцией. Сделайте его friend класса, если ему нужен доступ к private частям.

person Fred Foo    schedule 16.11.2011
comment
Лучше иметь общедоступную функцию toString и не нуждаться в friendship - person Benoit; 16.11.2011
comment
@Benoit: зависит от того, как выглядит класс. - person Fred Foo; 16.11.2011
comment
namespace BMV { typedef STD::vector‹BmvMessage*› BmvMessage_v_t; класс BmvMessage: public DboGenBmvMessage { private: COM::FldInt _element; общественность: DCS_DEF_CLASS (BmvMessage) недействительными getMessages (const COM:: FldString Msg); недействительными элементами копирования(); }; ; } #endif - person CodersSC; 16.11.2011
comment
это то, что класс выглядит как сообщение выше - person CodersSC; 16.11.2011
comment
@ShamariCampbell: я имел в виду комментарий Бенуа. Мой совет остается в силе. - person Fred Foo; 16.11.2011

Оператор должен быть свободной функцией, потому что его первый аргумент не имеет того же типа, что и ваш класс. Как правило, при перегрузке бинарного оператора Foo версия функции-члена принимает только один аргумент, а FOO(a, b) означает a.Foo(b).

Так как a << b вызовет a.operator<<(b), но a является потоком, это нам не нужно.

Так что сделайте бесплатную функцию или, возможно, бесплатную функцию друга. Наличие общедоступной функции-члена toString может помочь:

class Foo {
public:
  std::string toString() const;
  // ...
};

std::ostream & operator<<(std::ostream & o, const Foo & x) {
  return o << x.toString(); 
}
person Kerrek SB    schedule 16.11.2011

Вы используете сигнатуру произвольной формы для определения функции-члена. Функции-члены имеют неявный аргумент this, поэтому в вашем случае попытка вашей функции-члена перегрузить operator << приведет к функции, которая принимает 3 аргумента: неявные this, std::ostream& os и BmvMessage const& bm.

Вы не можете определить потоковые операторы как члены, так как первый аргумент должен относиться к классу потока. Вместо этого вы определяете их как бесплатные функции, возможно, связанные, если это необходимо.

person K-ballo    schedule 16.11.2011
comment
Я совершенно уверен, что неявные аргументы this здесь роли не играют. - person Kerrek SB; 16.11.2011
comment
@Kerrek SB: Нет, это было моей точкой зрения. Я думаю, я был недостаточно ясен - person K-ballo; 16.11.2011