2012-03-31 3 views
3

Mon code ressemble à:Ambigu surcharge pour stringstream

template <typename type> void deserialize_element(type* result) { 
    //... 
    if /*...*/ 
    else stringstream(line) >> *result; 
} 

MSVC compile sans problème, mais GCC donne:

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> 

Maintenant, j'ai vu des questions similaires ici sur Stack Overflow et ailleurs. Ceux-ci semblent concerner les personnes qui sous-classent la stringstream ou d'autres difficultés. En ce qui me concerne, cela devrait être aussi simple que d'appliquer ">>" à une chaîne de caractères ordinaire et un caractère? Pourquoi ça ne marche pas?

Merci,
Ian

Répondre

5

Je pense que le problème est un bug bien connu dans la façon dont MSVC++ gère rvalues. Dans la ligne

stringstream(line) >> *result; 

Vous créez un objet stringstream temporaire, puis d'invoquer operator >> dessus. Si operator >> est une fonction libre, sa signature prend probablement le paramètre stream par référence. Cependant, les objets temporaires, comme celui que vous avez construit ici, ne peuvent pas être transmis par référence. Visual Studio vous permet de faire cela même si cela n'est pas autorisé par la spécification C++, ce qui explique pourquoi cela fonctionne dans MSVC, mais g ++ ne le permet pas.

Pour résoudre ce problème, diviser cela en deux lignes:

stringstream stream(line); 
stream >> *result; 

Hope this helps!

+0

Merci pour l'explication! – imallett

+0

C++ 11 a une surcharge générique 'istream & operator >> (istream &&, T &)' IIRC. pas sûr pourquoi il ne déclenche pas ici sur GCC. –

+0

@ JohannesSchaub-litb- Peut-être que c'est une ancienne installation de g ++? – templatetypedef