Impliziter Konvertierungsoperator und Overload Resolution



  • Hallo

    Folgender Code kompiliert mit GCC aber nicht mit Clang.

    #include <cmath>
    
    template<typename T>
    struct wrapper
    {
    	T x;
    	operator T const&() const
    	{
    		return x;
    	}
    };
    
    int main()
    {
    	wrapper<double> a;
    	std::isinf(a);
    }
    

    Welcher Compiler hat Recht? Eine Instanz des Typs wrapper<double> kann implizit in double konvertiert werden; jedoch scheint es, als ob Clang die Konversion (und daher den Overload mit Parametertyp double ) gar nicht in Betracht zieht.

    LG



  • Welche clang-Version kompiliert das nicht? Habe mich eben auf godbolt durch ein paar durchgeklickt und da kompilierte es jeweils.

    Edit: habs auch lokal mit clang++-7 und clang++-6.0 erfolgreich kompiliert.



  • Er hat doch die Links gepostet.

    Nur haette er auch gleich die Fehlermeldung posten koennen:

    Start
    prog.cc:16:5: error: no matching function for call to 'isinf'
        std::isinf(a);
        ^~~~~~~~~~
    /opt/wandbox/clang-head/include/c++/v1/math.h:481:1: note: candidate template ignored: requirement 'std::is_arithmetic<wrapper<double> >::value' was not satisfied [with _A1 = wrapper<double>]
    isinf(_A1 __lcpp_x) _NOEXCEPT
    ^
    /opt/wandbox/clang-head/include/c++/v1/math.h:491:1: note: candidate template ignored: requirement 'std::is_arithmetic<wrapper<double> >::value' was not satisfied [with _A1 = wrapper<double>]
    isinf(_A1) _NOEXCEPT
    ^
    1 error generated.
    1
    Finish
    

    Der Hinweis auf std::is_arithmetic<wrapper<double> >::value sollte hilfreich sein.
    (ohne dass ich es jetzt genau beantworten koennte)


  • Mod

    Das Problem ist nicht clang selbst sondern libc++.
    Soweit ich sehe, sind dort die Math-Funktionen (im Wesentlichen) nicht als Overloads implementiert, sondern nutzen per SFINAE beschränkte Templates.
    Die SFINAE-Constraints sind offenkundig zu streng, allerdings dürfte selbst eine Berichtigung dieser der Standardspezifikation (die die Existenz 3er normaler Overloads verlangt) widersprechen: in jedem Fall wäre es einfach, ein standardkonformes Program zu schreiben, das sich im Falle der Templateimplementation anders verhält. Ganz nebenbei gibt libc++-isinf bool zurück, obwohl der Standard int verlangt.

    TL;DR: g++ hat recht. Bug by Design in libc++.



  • scrontch schrieb:

    Er hat doch die Links gepostet.

    Ah! Ich Idiot! Hatte da nicht drauf geklickt und dahinter generische Links zu GCC und Clang vermutet, nicht das konkrete Programm.


Log in to reply