LINUX.ORG.RU

operator<<, проблема


0

0

Задача: есть базовый класс (Element), есть наследник (Vertex), наследник должен выводить информацию через <<, в наследнике должен быть вызов оператора << в родительском классе, дабы и его родитель мог вывести информацию о себе. Для этого использую полиморфизм (Element)Vertex :

template <typename Type>
class Element
{
    friend ostream& operator<<(ostream& Out, Element<Type>& Source)
    {
        Out<<"Stuff from Element";
        return Out;
    };
};

template <typename Type>
class Vertex : public Element<Type>
{
    friend ostream& operator<<(ostream& Out, Vertex<Type>& Source)
    {
        return Out<<(Element<Type>)Source<<" and some stuff from Vertex";
    };
};

При сборке строка

return Out<<(Element<Type>)Source<<" and some stuff from Vertex";
подсвечивается, и на ней компилятор выдаёт длинную гневную фразу, общий смысл которой:

«no match for 'operator<<' in Out << Element<int>(тут очень много букв)».

Вроде бы оператор<< в родительском классе объявлен. Что я делаю не так, и как делать правильно?

★★★★★

Последнее исправление: jcd (всего исправлений: 3)

Ответ на: комментарий от tia

..\/graph.h:155: error: no match for 'operator<<' in 'Out << Element<unsigned int>(((const Element<unsigned int>&)((const Element<unsigned int>*)(&((Vertex<unsigned int>*)Source)->Vertex<unsigned int>::<anonymous>))))'

jcd ★★★★★
() автор топика

Что может помешать сделать в классе Element метод virtual void print(ostream& stream) и просто вызывать его когда надо?

Absurd ★★★
()
Ответ на: комментарий от Absurd

Сделал, работает. Благодарю. :)

Но всё же интересно, что именно там мешает сделать так, как я хотел изначально?

jcd ★★★★★
() автор топика
Ответ на: комментарий от jcd

>Но всё же интересно, что именно там мешает сделать так, как я хотел изначально?

Здравый смысл, не испохабленный ++-фагготрией.

Absurd ★★★
()
Ответ на: комментарий от Absurd

Здравый смысл как раз подсказывает, что путь полиморфизма как бы более корректный.

jcd ★★★★★
() автор топика

Проблема глубже - она в том, что только полный придуроктруп страуса мог додуматься использовать оператор битового сдвига влево для вывода в поток.

Love5an
()
Ответ на: комментарий от jcd

>Здравый смысл как раз подсказывает, что путь полиморфизма как бы более корректный.

Здравый смысл - это всегда делать самую простую вещь, которая будет работать.

Absurd ★★★
()

>friend ostream& operator<<(ostream& Out, Element<Type>& Source)

friend ostream& operator<<(ostream& Out, const Element<Type>& Source)

friend ostream& operator<<(ostream& Out, Vertex<Type>& Source)

friend ostream& operator<<(ostream& Out, const Vertex<Type>& Source)

1. Выучи язык, на котором пытаешься писать

2. Никогда не используй std::*stream

linuxfan
()
Ответ на: комментарий от linuxfan

>Никогда не используй std::*stream

Почему это? Альтернативы есть?

Elverion
()
Ответ на: комментарий от linuxfan

В том месте он уже не ругается, видимо работает как надо. Спасибо. И в догонку:

friend ostream& operator<<(ostream& Out, const Element<Type>& Source)
{
    Out<<Source.Func();
    return Out;
};

..\/graph.h:153: error: passing 'const Element<unsigned int>' as 'this' argument of 'guint8 Element<Type>::Func() [with Type = unsigned int]' discards qualifiers

Как я понимаю - ему не нравится, что Func() может повредить константность класса Source, которому она принадлежит. Как показать, что Func() в своём классе ничего не меняет?

Выучи язык, на котором пытаешься писать

Процесс в самом разгаре.

jcd ★★★★★
() автор топика
Ответ на: комментарий от degeron

Оно самое, и я почти счастлив. Спасибо всем помогавшим!

jcd ★★★★★
() автор топика
Ответ на: комментарий от Absurd

> Что может помешать сделать в классе Element метод virtual void print(ostream& stream) и просто вызывать его когда надо?

Можно вдобавок сделать один << только для базового класса, который будет print дёргать. Ну и благодаря желанному полиморфизму, под него подойдёт и дочерний класс и напечатается правильно.

const86 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.