g++, Fehlermeldung bei cast operatoren



  • #include <string>
    
    struct test
    {
    	operator std::string()  const { return ""; }
    	operator unsigned int() const { return 12; }
    
    	template <typename T>
    	operator T&() { return T(); } // nur zu Testzwecken!
    };
    
    int main()
    {
    	const test value;
    	std::string tmp = static_cast<std::string>(value);
            // std::string tmp = value;
    }
    

    Wenn man das normal compiliert, dann meldet g++(4.8.0):

    ped.cpp: In function 'int main()':
    ped.cpp:16:50: error: call of overloaded 'basic_string(const test&)' is ambiguous
    ped.cpp:16:50: note: candidates are:
    In file included from string:54:0,
                     from ped.cpp:2:
    basic_string.h:519:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::initializer_list<_CharT>, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match>
    basic_string.h:519:7: note:   no known conversion for argument 1 from 'const test' to 'std::initializer_list<char>'
    basic_string.h:504:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(std::basic_string<_CharT, _Traits, _Alloc>&&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>] <near match>
    basic_string.h:504:7: note:   no known conversion for argument 1 from 'const test' to 'std::basic_string<char>&&'
    basic_string.h:487:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match>
    basic_string.h:487:7: note:   no known conversion for argument 1 from 'const test' to 'const char*'
    basic_string.h:452:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const std::basic_string<_CharT, _Traits, _Alloc>&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>; std::basic_string<_CharT, _Traits, _Alloc> = std::basic_string<char>] <near match>
    basic_string.h:452:7: note:   no known conversion for argument 1 from 'const test' to 'const std::basic_string<char>&'
    basic_string.h:445:7: note: std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = std::allocator<char>] <near match>
    basic_string.h:445:7: note:   no known conversion for argument 1 from 'const test' to 'const std::allocator<char>&'
    

    Wenn man allerdings -pedantic mitgibt, dann ist der Fehler weg.
    Wer hat recht? g++ oder g++?



  • template <typename T> 
        operator T&() { return T(); } // nur zu Testzwecken!
    

    Edit: Jo, das geht für OR, weil die Funktion nicht instantiiert wird, bevor sie nicht der beste Match ist.

    Alles andere war falsch.


  • Mod

    gcc hat eine Reihe von Bugs mit Konvertierungsoperatoren.
    Der T&-Operator sollte eigentlich irrelevant sein, weil er nicht auf ein const-Objekt angewendet werden kann.
    Die Implementierung spielt dabei keine Rolle (die ist übnrigens nicht per se problematisch: T könnte const sein, oder einen Konvertierungsoperator für T& haben).
    Interessant auch, dass sich der Compiler nicht über die Zeile darüber beschwert.



  • camper schrieb:

    Interessant auch, dass sich der Compiler nicht über die Zeile darüber beschwert.

    Ich musste erst clang drüberlaufen lassen, bis mir das überhaupt aufgefallen ist.
    Anscheinend war g++ da früher sogar mal besser: http://stackoverflow.com/questions/4674332/declaring-a-const-instance-of-a-class


Anmelden zum Antworten