operator << stackoverflow

Cal*_*602 7 c++ visual-studio-2010

请考虑以下代码:

class TextMessage{
public :
    TextMessage(){};
    TextMessage(std::string _text):text(_text){}
    std::string text;
    friend std::ostream & operator<<( std::ostream & os, const TextMessage & m);
};
std::ostream & operator<<( std::ostream & os, const TextMessage & m){
    return os << "text message : " << m.text;
}
Run Code Online (Sandbox Code Playgroud)

为什么在地球上:

  • Visual 2010 是否在操作员中发出C4717警告<<
  • 是否std::cout << textMsgInstance;由Visual预测的stackoverflow崩溃?

顺便说一句,取而代之的m.textm.text.c_str()作品.

Pup*_*ppy 14

我猜你没错#include <string>.因此,当编译器输出a时std::string,它不能,并开始寻找隐式转换 - 而对TextMessage的隐式构造函数看起来就像是账单.但等等 - 现在我们在TextMessage的输出函数和bam中输出一个TextMessage.

  • @Ben:Visual C++标准库实现中除了`<string>`之外的一些头文件引入了`std :: string`,但只有`<string>`引入了流操作符重载.例如,如果你#include <iostream>`(并且不包括`<string>`),那么`int main(){std :: string s; }`将工作,但`int main(){std :: string s; std :: cout << s; "不会. (4认同)
  • 我也这么认为,但是在将std :: string`用作(非指针)成员变量之前,它不需要是一个完整的类型吗?显然,这是缺少流插入操作符. (3认同)
  • @DeadMG你能指出标准中的"全部或部分"吗?我在我的副本中找到的是(第17.4.4.1节)"C++标头可能包含其他C++标头." 没有提到零件.(显然,这是一个学术问题:是否只包含一部分是合法的,这是大多数实现所做的,我们必须忍受它.) (3认同)
  • 如果这是正确的,那么声明构造函数`explicit`是一个很好的理由...... (2认同)

Eel*_*lke 6

我唯一能想到的是它没有运算符<< for std :: string所以它寻找转换并找到一个参数构造函数TextMessage(std :: string).

通常建议通过使它们显式来防止对一个参数构造函数的意外调用.

explicit TextMessage(std::string _text):text(_text){}
Run Code Online (Sandbox Code Playgroud)

然后它不会考虑隐式转换的构造函数.