Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Ambiguous Overload for stringstream

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?

like image 511
imallett Avatar asked Dec 29 '25 01:12

imallett


1 Answers

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!

like image 91
templatetypedef Avatar answered Dec 31 '25 14:12

templatetypedef