[英]Why does operator<< not work with something returned by operator-?
這是我編寫的一個小型測試程序:
#include <iostream>
using namespace std;
class A {
public:
int val;
A(int _val=0):val(_val) { }
A operator+(A &a) { return A(val + a.val); }
A operator-(A &a) { return A(val - a.val); }
friend ostream& operator<<(ostream &, A &);
};
ostream& operator<<(ostream &out, A &a) {
out<<a.val;
return out;
}
int main() {
A a(3), b(4), c = b - a;
cout<<c<<endl; // this works
cout<<(b-a)<<endl; // this doesn't
return 0;
}
我似乎無法理解為什么標記為“ this works”的行有效而標記為“ this not's”的行卻無效。 當我嘗試使用cout<<(ba);
編譯程序時cout<<(ba);
行,這是我得到的:
[felix@the-machine C]$ g++ test.cpp
test.cpp: In function ‘int main()’:
test.cpp:26:13: error: no match for ‘operator<<’ in ‘std::cout << b.A::operator-(((A&)(& a)))’
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:108:7: note: candidates are: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ostream_type& (*)(std::basic_ostream<_CharT, _Traits>::__ostream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:117:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__ios_type& (*)(std::basic_ostream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>, std::basic_ostream<_CharT, _Traits>::__ios_type = std::basic_ios<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:127:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(std::ios_base& (*)(std::ios_base&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:165:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:169:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:173:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(bool) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/ostream.tcc:91:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(short int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:180:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(short unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/ostream.tcc:105:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(int) [with _CharT = char, _Traits = std::char_traits<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:191:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:200:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:204:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long long unsigned int) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:209:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:213:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(float) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:221:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(long double) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/ostream:225:7: note: std::basic_ostream<_CharT, _Traits>::__ostream_type& std::basic_ostream<_CharT, _Traits>::operator<<(const void*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__ostream_type = std::basic_ostream<char>]
/usr/lib/gcc/i686-pc-linux-gnu/4.5.0/../../../../include/c++/4.5.0/bits/ostream.tcc:119:5: note: std::basic_ostream<_CharT, _Traits>& std::basic_ostream<_CharT, _Traits>::operator<<(std::basic_ostream<_CharT, _Traits>::__streambuf_type*) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_ostream<_CharT, _Traits>::__streambuf_type = std::basic_streambuf<char>]
test.cpp:18:11: note: std::ostream& operator<<(std::ostream&, A&)
[felix@the-machine C]$
真討厭。
您的operator +返回一個臨時對象-在C ++中,您不能將臨時對象綁定到非const引用。 你要:
ostream& operator<<(ostream &out, const A &a) {
這是寫opertaor <<以進行流傳輸的規范方法-輸出的內容應始終作為const引用傳遞。
因為您不允許將臨時信息傳遞給插入運算符。 更改為:
friend ostream& operator<<(ostream &, const A &);
...
ostream& operator<<(ostream &out, const A &a) {
out<<a.val;
return out;
}
在第二行中,您要求編譯器將A從A轉換為A&,但是A是臨時的,這是非標准行為。 在第一行中,c不是臨時的,因此可以正常工作。 將您的運算符更改為
ostream& operator<<(ostream &out, const A &a)
不僅會更正確,而且還應被編譯器接受。
您正在將一個臨時對象傳遞給operator<<
,因此它需要采用const A&
。
std::ostream& operator<<(std::ostream&, const A&)
其他一些注意事項:
傳遞未修改的非原始參數時,請始終使用“ const T&”。 這允許您傳遞臨時消息,並指示您不更改參數。
最好將單參數構造函數標記為explicit
,這可以防止您在各處創建意外的臨時對象,從而降低性能。
explicit A(int _val=0):val(_val) { }
臨時對象基本上被認為是const
,因此對於綁定到它的引用,它必須是對const的引用:
ostream& operator<<(ostream &out, A const &a) // ...
std::basic_ostream::operator<<
需要用例中的const限定參數。 因此,您需要按以下步驟更正操作員的簽名:
ostream& operator<<(ostream &out, A const& a)
順便說一句,友誼是多余的,因為A::val
是公開的,因此無論如何都可以訪問。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.