我錯過了std::wostream::operator<<()
這個std::string
。 這裏是最小的測試案例說明我的問題:使用`std :: wostream`和`std :: string`重載`operator <<`時,出現「no match」和「can not bind lvalue」錯誤。
#include <string>
#include <sstream>
inline std::wostream &operator<<(std::wostream &os, const std::string &)
{
return os;
}
class FakeOstream{};
namespace mynamespace {
class FakeClasse1 {
friend inline FakeOstream &operator<<(FakeOstream &out, const FakeClasse1 &) {
return out;
}
};
class FakeClasse2 {
friend inline FakeOstream &operator<<(FakeOstream &out, const FakeClasse2 &) {
return out;
}
};
void test()
{
auto mystring = std::string{u8"mystring"};
std::wostringstream s;
s << mystring; // The errors occur here
}
} // namespace mynamespace
的代碼可以編譯和在此執行:http://cpp.sh/9emtv
正如你可以在這裏看到,有一個operator<<
與std::wostream
和std::string
過載。除了聲明 和FakeOstream
以及他們自己之外,兩個假等級是空的。 test()
函數 實例化一個std::wostringstream
併爲其提供std::string
。僞造的類和測試函數位於命名空間中。
此代碼產生上cpp.sh以下錯誤在該行s << mystring;
:
In function 'void mynamespace::test()':
25:10: error: cannot bind 'std::basic_ostream<wchar_t>' lvalue to 'std::basic_ostream<wchar_t>&&'
In file included from /usr/include/c++/4.9/istream:39:0,
from /usr/include/c++/4.9/sstream:38,
from 2:
/usr/include/c++/4.9/ostream:602:5: note: initializing argument 1 of 'std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = wchar_t; _Traits = std::char_traits<wchar_t>; _Tp = std::basic_string<char>]'
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
當使用直接克++(5.3.0版本從MSYS2),一個no match error
也 顯示:
./tmpbug.cpp: In function 'void mynamespace::test()':
./tmpbug.cpp:25:7: error: no match for 'operator<<' (operand types are 'std::wostringstream {aka std::__cxx11::basic_ostringstream<wchar_t>}' and 'std::__cxx11::basic_string<char>')
s << mystring;
^
In file included from C:/Appli/msys64/mingw64/include/c++/5.3.0/istream:39:0,
from C:/Appli/msys64/mingw64/include/c++/5.3.0/sstream:38,
from ./tmpbug.cpp:2:
C:/Appli/msys64/mingw64/include/c++/5.3.0/ostream:628:5: note: candidate: std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = wchar_t; _Traits = std::char_traits<wchar_t>; _Tp = std::__cxx11::basic_string<char>] <near match>
operator<<(basic_ostream<_CharT, _Traits>&& __os, const _Tp& __x)
^
C:/Appli/msys64/mingw64/include/c++/5.3.0/ostream:628:5: note: conversion of argument 1 would be ill-formed:
./tmpbug.cpp:25:10: error: cannot bind 'std::basic_ostream<wchar_t>' lvalue to 'std::basic_ostream<wchar_t>&&'
s << mystring;
^
In file included from C:/Appli/msys64/mingw64/include/c++/5.3.0/istream:39:0,
from C:/Appli/msys64/mingw64/include/c++/5.3.0/sstream:38,
from ./tmpbug.cpp:2:
據我所知,示例中的所有部分都是必需的,以便出現 的錯誤。如果我註釋掉虛假類中的名稱空間,假類或其中一個,那麼代碼編譯就會很好。此外,如果我只是將其中一個假類或測試函數移動到名稱空間之外,那麼代碼也會編譯得很好。
此外,我嘗試使用編譯器 從http://cppreference.com編譯叮噹3.7這個例子,代碼似乎編譯沒有問題。
有沒有我的代碼有問題,或者這是一個GCC錯誤?如果這是一個海灣合作委員會的錯誤,是 有一個解決方法?
如果代碼頂部編譯那麼什麼代碼產生的錯誤? – NathanOliver
代碼不能編譯,至少在GCC上。錯誤發生在行的
Basile
對我來說看起來像名稱查找問題,但我無法猜測正確的行爲是什麼。將'using :: operator <<;'''添加到'test'是我能找到的最小解決方法。 (爲'std'添加重載以啓用依賴於參數的查找也會導致問題消失,但我不確定這是多麼有效。) – molbdnilo