簡體   English   中英

重載后 std::endl 的“operator<<”不匹配

[英]no match for ‘operator<<’ for std::endl after overload

很抱歉我重復了這個問題,但我沒有在那里發表評論所需的聲譽,而且那里的答案對我來說沒有說服力。

#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*)(& str))))) << std::endl' 中沒有匹配'operator<<'

我不明白為什么。 如果它適用於 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 代碼證明是非常困難的,所以我很感激任何見解。

簡單的重載確實解釋了這個錯誤。 事實上, 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;
}

……但當然這只能解決您的一些問題,因為您的類定義在語義上是錯誤的; 你不能像這樣子類化 IO 流。 在這里,我的知識失敗了,但我認為為了做你想做的事,你應該覆蓋流緩沖區的uflow函數。

解決此問題的另一種方法是將運算符<< 重載聲明為友元。

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

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

   template <class T>
     friend my_ostream& operator<<(my_ostream& my_os, const T& s){
        std::cout << my_os.prefix << s;
     return my_os;
   }
};

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM