My code looks something like:
template <typename type> void deserialize_element(type* result) {
//...
if /*...*/
else stringstream(line) >> *result;
}
MSVC compiles without an issue, but GCC gives:
error: ambiguous overload for 'operator>>' in 'std::basic_stringstream<char>(((const std::basic_stringstream<char>::__string_type&)((const std::basic_stringstream<char>::__string_type*)(& line))), std::operator|((std::_Ios_Openmode)16u, (std::_Ios_Openmode)8u)) >> * result'
/usr/include/c++/4.5/istream:120:7: note: candidates are: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__istream_type& (*)(std::basic_istream<_CharT, _Traits>::__istream_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>] <near match>
/usr/include/c++/4.5/istream:124:7: note: std::basic_istream<_CharT, _Traits>::__istream_type& std::basic_istream<_CharT, _Traits>::operator>>(std::basic_istream<_CharT, _Traits>::__ios_type& (*)(std::basic_istream<_CharT, _Traits>::__ios_type&)) [with _CharT = char, _Traits = std::char_traits<char>, std::basic_istream<_CharT, _Traits>::__istream_type = std::basic_istream<char>, std::basic_istream<_CharT, _Traits>::__ios_type = std::basic_ios<char>] <near match>
Now, I've seen some similar questions here on Stack Overflow and elsewhere. These appear to deal with people subclassing stringstream or other dodginess. As far as I'm concerned, this should just be as simple as applying ">>" to an ordinary stringstream and a char? Why isn't this working?
I think the issue is a well-known bug in how MSVC++ handles rvalues. In the line
stringstream(line) >> *result;
You are creating a temporary stringstream object, then invoking operator >> on it. If operator >> is a free function, its signature probably takes the stream parameter by reference. However, temporary objects, like the one you've constructed here, cannot be passed by reference. Visual Studio lets you do this even though it's not allowed by the C++ spec, which is why this works in MSVC, but g++ does not allow this.
To fix this, split this into two lines:
stringstream stream(line);
stream >> *result;
Hope this helps!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With