нет совпадения с оператором & lt; & lt; для std :: endl после перегрузки

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

#include<iostream>

class my_ostream : public std::ostream
{
public:
std::string prefix;

my_ostream():prefix("*"){}

my_ostream& operator<<(const std::string &s){
std::cout << this->prefix << s;
return *this;
}
};

int main(){
my_ostream s;
std::string str("text");
s << str << std::endl;
}

Здесь я получаю:

нет совпадения для оператора ‘<<В ‘s.my_ostream :: operator<<(((const std :: string&) ((const std :: string *) (& ул)))) << станд :: епсИ»

и я не понимаю почему. Если это работает для ostream, оно должно работать для my_ostream. Эта программа работает:

#include <iostream>
using namespace std;

class a{};
class b:public a{};
class c:public b{};

void f(a){cout << 'a' << endl;}
void f(b){cout << 'b' << endl;}
void f(b, a){cout << "b, a" << endl;}
void f(c){cout << 'c' << endl;}
void f(c, int){cout << "c, int" << endl;}

void f(a*){cout << "pa" << endl;}
void f(b*){cout << "pb" << endl;}
void f(b*, a*){cout << "pb, pa" << endl;}
void f(c*){cout << "pc" << endl;}
void f(c*, int){cout << "pc, int" << endl;}

int main(){
a ao; b bo; c co;
f(ao); f(bo); f(co);
f(co, ao);
a *pa=new(a); b *pb=new(b); c *pc=new(c);
f(pa); f(pb); f(pc);
f(pc, pa);
return 0;}

Это выводит:

a
b
c
b, a
pa
pb
pc
pb, pa

Простая перегрузка не объясняет эту ошибку. Кроме того, я не привожу здесь шаблоны, поэтому неопределенные параметры типа шаблона не должны играть роли. Чтение кода iostream оказывается очень трудным, поэтому я ценю любую информацию.

1

Решение

Простая перегрузка делает объясните эту ошибку. По факту, std::cout только усложняет проблему. Следующее также не работает:

int main(){
my_ostream s;
s << 1;
}

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

Грубо говоря, C ++ выполняет перегрузку после разрешения области видимости. Итак, C ++ сначала проверяет, есть ли operator << определяется в рамках вашего класса. Есть! Таким образом, он прекращает поиск более общих функций и рассматривает только те функции, которые уже найдены для разрешения перегрузки. Увы, есть только одна перегрузка, для std::string так что вызов не проходит.

Это можно исправить, просто определив operator << не как функция-член, а как свободная функция:

my_ostream& operator<<(my_ostream& out, const std::string &s) {
std::cout << out.prefix << s;
return out;
}

… Но, конечно, это только устраняет некоторые из ваших проблем, потому что ваше определение класса просто семантически неверно; Вы не можете разделить потоки ввода-вывода подобным образом. Здесь мои знания терпят неудачу, но я думаю, что для того, чтобы делать то, что вы хотите, вы должны переопределить буфер потока uflow функция.

2

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]