Перегрузка операторов и написание манипуляторов? - PullRequest
0 голосов
/ 07 января 2012

Хорошо, я не могу заставить этот код работать: я хочу объединить свои пользовательские манипуляторы.поэтому они будут называться как cout << endl называется.например, я хочу это:

   emit << event1 << event2 << event3;

вот мой код:

class Emit
{
public:
                // ...
    const void operator<<(const Event& _event) const;
}const emit; // note this global

inline const void Emit::operator<<(const Event& _event) const
{
    Start(_event);
}


class Event 
{
               // ...
         const Event& Event::operator<<(const Event& _event) const;
};

inline const Event& Event::operator<<(const Event& _event) const
{
    return _event;
}

Однако я не могу назвать это:

 emit << event1 << event2 << event3;

Я получаю компиляциюошибка времени, ошибки времени ссылки и что бы я ни изменил в своем коде, я получаю сообщение об ошибке coresponding безуспешно.

, например, это:

Ошибка 1, ошибка C2679: двоичная '<<': не найден оператор, который принимает правый операнд типа' const EventHandling :: Event '(или нет приемлемого преобразования) c: \ users \ admin \ documents \ visual studio 2010 \ projects \ cppsystem \ eventhandling \ test.h 18 </p>

большое спасибо.

Ответы [ 2 ]

2 голосов
/ 07 января 2012

Эти операторы вызываются слева направо. Таким образом, первый вызов (emit << event1) должен возвращать ссылку на Emit:

class Emit
{
public:
    // ...
    Emit const& operator<<(const Event& _event) const;
}const emit; // note this global

Emit const& Emit::operator<<(const Event& _event) const
{
    Start(_event);
    return *this;
}

И теперь вам больше не нужно перегружать operator<< в вашем классе Event.

1 голос
/ 07 января 2012

Если ваши манипуляторы не содержат каких-либо данных, вы можете просто написать функцию.Например, std::endl реализован примерно так (ему нужно также справиться с широкими потоками и, таким образом, нужно что-то волшебное, чтобы организовать преобразование символов):

std::ostream& endl(std::ostream& out) {
    (out << '\n').flush();
    return out;
}

Если ваши манипуляторы имеют некоторые данные, которые вынеобходимо сохранить данные в подходящем объекте, а затем просто создать нормальный оператор вывода для этого класса, например, std::setw() может быть реализовано следующим образом (опять же, игнорируя, что потоки на самом деле являются шаблонами):

struct std::setw {
    setw(int size): size_(size) {}
    int size_;
};
std::ostream& operator<< (std::ostream& out, std::setw const& object) {
    out.width(object.size_);
    return out;
}

Вы можете реализовать операторы вывода в качестве члена, потому что вы не управляете левой стороной operator<<(): здесь находится объект потока.Если бы вы реализовывали std::ostream, вы могли бы реализовать эти члены (ну, на самом деле, стандартные требования, согласно которым определенные операторы вывода являются членами std::ostream).

...