Konstructor aufrufbarkeit prüfen



  • Hi,
    kennt jemand eine Möglichkeit wie man ermitteln könnte mit welchen Parametern ein Konstruktor aufrufbar ist? - sprich ob eine bestimmte Konstruktor-Überladungen existieren?

    in vorraus dankend
    der ctor



  • Man ruft ihn mit den Parametern auf und hält nach Fehlermeldungen des Compilers Auschau.



  • dies würde ich allerdings in der Compilierungszeit ermitteln, sodas ich ein boolschen rückgabewert bekomme.
    z.B.

    struct X
    {
      X(int,int,int);
      X(string);
      X(float);
    };
    
    int main()
    {
      std::cout << ist_ctor_von<X>::so_aufrufbar<int,int,int>::value ;
    }
    

    Ich möchte das für eine Template-klasse mit templatesierten konstruktor, um diverse konstruktoren auszuschließen, damit std::is_convertible richtige ergebnisse liefert.



  • Das geht AFAIK nur in C++0x (und zwar mit SFINAE), ungetestet (und da gibt es bei mir bei SFINAE erfahrungsgemäß am Anfang viele Fehler):

    #include <iostream>
    
    template<typename T> T create_helper();
    
    template<typename T> class SFINAE
    {
        typedef struct{T[2] tmp;} False_Help;
        template<typename... Args> static auto Has_This_Constructor(T in) -> decltype(T(create_helper<Args>()...));
        template<typename... Args> static False_Help Has_This_Constructor(...);
    }
    
    template<typename T, typename... Args> bool HasConstructor
    {
        return sizeof(SFINAE<T>::Has_This_Constructor<Args...>(create_helper<T>())) == sizeof(T);
    }
    
    int main()
    {
        std::cout << std::boolalpha << HasConstructor<int, int>() << "\n";
    }
    

    ABER: Möchtest du abhängig davon einen unterschiedlichen Konstruktor aufrufen, brauchst du überladene Klassen mit einem Boolean-Parameter, der von dem sizeof()-Vergleich abhängt. (also les dir das in aller Ruhe nochmal durch, ich hab auch eine Weile gebraucht)



  • HALT: ich habe doch schon mal fast das gleiche geschrieben:
    http://www.c-plusplus.net/forum/274260-30



  • Super, genau sowas wollte ich!!

    allerdings funktioniert es bei mir noch nicht ganz, sobald ich eine falsche Parameterkombi teste, fängt der Compiler an zu meckern.

    template<typename T> T create_helper();
    
    template<typename T> struct SFINAE
    {
        typedef struct{T tmp[2];} False_Help;
        template<typename... Args> static auto Has_This_Constructor(T in) -> decltype(T(create_helper<Args>()...));
        template<typename... Args> static False_Help Has_This_Constructor(...);
    };
    
    template<typename T, typename... Args> bool HasConstructor()
    {
        return sizeof(SFINAE<T>::template Has_This_Constructor<Args...>(create_helper<T>())) == sizeof(T);
    }
    
    int main()
    {
        std::cout << std::boolalpha << HasConstructor<int, int,int>() << "\n";
    }
    

    bei zeile 8 : |error: functional cast expression list treated as compound expression|

    Des weiteren bin ich mir nicht sicher, ob es richtig ist es nach der Größe von False_Help zu testen(was ist wenn eine andere Klasse gleichgroß ist?).



  • ups meine zeile 6...



  • 1. Welchen Compiler verwendest du und unterstützt der C++0x? Ich verwende GCC 4.5.1.
    2. Nimm doch mal meine Lösung von Seite 4 unten meines Threads und änder sie ein wenig ab, die ist nämlich getestet.


Log in to reply