在过载之后没有针对std :: end1的'operator<<'的匹配 [英] no match for ‘operator<<’ for std::endl after overload

查看:191
本文介绍了在过载之后没有针对std :: end1的'operator<<'的匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

很抱歉,我重复了此问题,但我没有必要的声誉,在那里评论,那里的答案不能说服我。

I am sorry that I duplicate this question, but I don't have the reputation required to comment there and the answers there are not convincing for me.

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

这里我得到:


不匹配'operator

no match for ‘operator<<’ in ‘s.my_ostream::operator<<(((const std::string&)((const std::string*)(& str)))) << std::endl’

我不明白为什么。如果它适用于ostream,它应该为my_ostream工作。此程序的工作原理:

and I don't understand why. If it works for ostream, it should work for my_ostream. This program works:

#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代码证明是非常困难的,所以我欣赏任何洞察。

So simple overloading does not explain this error. Also, I do not introduce templates here, so undetermined template type parameters should not play a role. Reading the iostream code proves to be very difficult, so I appreciate any insight.

推荐答案

简单重载解释此错误。事实上, std :: cout 只是使问题复杂化。以下也不起作用:

Simple overloading does explain this error. In fact, std::cout just complicates the issue. The following also doesn’t work:

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


$ b <

The issue is that your operator << overload in effect hides all the overloads that are defined for the base class.

大致来说,C ++超载了分辨率。因此,C ++首先检查是否在类的范围中定义了运算符<< 。有!所以它停止搜索更一般的函数,只考虑已经发现的重载分辨率的函数。唉,只有一个重载, std :: string 所以调用失败。

Roughly speaking, C++ does overload resolution after scope resolution. So C++ first checks if there’s an operator << defined in the scope of your class. There is! So it stops searching for more general functions right there and only considers the functions already found for overload resolution. Alas, there’s only a single overload, for std::string so the call fails.

简单地定义运算符<< <不是成员函数,而是一个自由函数:

This can be fixed simply by defining operator << not as a member function but a free function:

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

...但是这只修复了一些问题,只是语义错误;你不能这样子类化IO流。这里我的知识失败,但我想为了做你想要你应该重写流缓冲区的 uflow 函数。

… but of course this only fixes some of your problems because your class definition is simply semantically wrong; you cannot subclass the IO streams like this. Here my knowledge fails but I think in order to do what you want you should override the stream buffer’s uflow function.

这篇关于在过载之后没有针对std :: end1的'operator&lt;&lt;'的匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆