![](/img/trans.png)
[英]Why does it not work to overload “operator <<” on std::string?
[英]Global overload of operator<< does not work, why?
我了解到operator<<可以通過使其成為 class 的朋友 function 來重載。 例如,
struct Test
{
std::string d_data;
Test(const std::string & data) : d_data{data} {}
friend std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
ostr << obj.d_data << '\n';
return ostr;
}
};
int main()
{
Test t1("one");
std::cout << t1;
Test t2("two");
std::cout << t2;
}
one two
這似乎按預期工作。
但是,我無法理解為什么同樣的方法不適用於全局過載。
#include <iostream>
#include <ostream>
#include <string>
std::ostream & operator<<(std::ostream & os, const std::string & s)
{
os << s << '\n';
return os;
}
int main()
{
std::cout << "stackoverflow";
std::cout << "stackoverflow";
}
stackoverflowstackoverflow
期望字符串用換行符分隔,但沒有按預期工作。
您的運營商使用
std::cout << "stackoverflow";
需要從const char *
類型的 object (在將字符串文字隱式轉換為指向其第一個字符的指針之后)到std::string
類型的 object 的用戶定義轉換。
然而,標准 basic_ostream class 已經有一個不需要這種轉換的運算符
template<class charT, class traits>
basic_ostream<charT, traits>& operator<<(basic_ostream<charT, traits>&, const char*);
所以這個操作符被調用而不是你的操作符。
此外,在您的運營商內
std::ostream & operator<<(std::ostream & os, const std::string & s)
{
os << s << '\n';
return os;
}
有自己的遞歸調用。
您可以通過以下方式定義您的運營商
#include <iostream>
#include <string>
std::ostream & operator<<(std::ostream & os, const char *s)
{
return std::operator <<( os, s ) << '\n';
}
int main()
{
std::cout << "stackoverflow";
std::cout << "stackoverflow";
}
並得到預期的結果
stackoverflow
stackoverflow
請注意, "stackoverflow"
是const char[]
類型,但不是std::string
類型。 這意味着不會調用您的重載,但會調用標准庫( operator<<(std::basic_ostream)
中的重載,因為它是完全匹配的並且不需要從const char[]
到std::string
。
template< class Traits > basic_ostream<char,Traits>& operator<<( basic_ostream<char,Traits>& os, const char* s );
順便說一句:因為ADL可以找到它。
您可以全局重載,但"stackoverflow"
不是std::string
,因此不使用您的。
(而且標准庫中已經存在這樣的重載。)
要查看它是否有效,請將您的第一個重載移出 class 定義並使其成為非朋友。
必須將其聲明為friend
的唯一原因是您已在 class 定義中聲明它,否則它將是成員 function 。
這將按您的預期工作:
struct Test
{
std::string d_data;
Test(const std::string & data) : d_data{data} {}
};
std::ostream & operator<<(std::ostream & ostr, const Test & obj)
{
ostr << obj.d_data << '\n';
return ostr;
}
int main()
{
Test t1("one");
std::cout << t1;
Test t2("two");
std::cout << t2;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.