methode deaktivieren



  • dumme frage aber:

    template<int i>
    struct foo
    {
    	void f(int, char){}
    	void f(int){} //<--
    };
    

    die methode hier will ich deaktivieren wenn i != 1 ist. wie mache ich das? crtp geht nicht weil es mehrere f gibt (hier im beispiel nur zwei) und die bei vererbung dann ja verdeckt werden. enable_if geht nicht weil die methode unbedingt instanziiert wird da sie kein template ist.


  • Mod

    z.B.

    template<int i>
    struct foo
    {
        void f(int, char){}
        template <typename enable_if<i==1,int>::type=0>
        void f(int){}
    };
    


  • geht das auch iwie in c++03 wo's noch keine default-template-argumente gibt? ne zweite private methode die ein argument verlangt und die dann von der echten funktion aufgerufen wird mit dummy-template-argument? hmm naja ich hätte auch nen globalen funktor schreiben können und den iwie spezialisieren, hab aber gehofft es gibt was eleganteres. danke!



  • es geht nicht wenn ichs auslagere 😞 http://ideone.com/1ZUCJf

    template<bool, typename>
    struct enable_if
    {
    };
    template<typename T>
    struct enable_if<true, T>
    {
    	typedef T type;
    };
    
    template<int i>
    struct foo
    {
    	template <typename enable_if<i==1, int>::type>
        void helper(int){}
    
        void f(int, char){}
        void f(int z){ helper<0>(z); }
    };
    
    int main()
    {
    	foo<2> k;
    	k.f(0, 0);
    }
    

    andere ideen?


  • Mod

    template<bool, typename=void>
    struct enable_if {};
    template<typename T>
    struct enable_if<true, T> { typedef T type; };
    
    template <typename T, typename U>
    struct is_convertible
    {
        typedef char no[1];
        typedef char yes[2];
        static T makeT();
        static no& test(...);
        static yes& test(U);
        static const bool value = sizeof(test(makeT())) == sizeof(yes);
    };
    
    template<int i>
    struct foo
    {
        void f(int, char){}
        template <typename T>
        typename enable_if<i==1&&is_convertible<T,int>::value>::type f(T){}
    };
    
    int main()
    {
        foo<1> x; x.f(0,0); x.f(0);
        foo<2> y; y.f(0,0); //y.f(0);
    }
    


  • mhh ok, das wäre i.o.

    kannst du mir mal bitte sagen, ob das hier theoretisch korrekt wäre? (mit gcc gehts zumindest)
    ist mir gerade noch in den sinn gekommen als ich an boosts static_assert gedacht hab.

    template<int i>
    struct foo
    {
    	void f(int, char){}
        void f(int){ char dummy[i == 1 ? 1 : -1]; }
    };
    
    int main()
    {
        foo<1> x; x.f(0,0); x.f(0);
        foo<2> y; y.f(0,0); //y.f(0);
    }
    

  • Mod

    Ja, das ist korrekt. Memberfunktionen werden nicht automatisch mit der Klasse instantiiert.


  • Mod

    hanstroll123 schrieb:

    kannst du mir mal bitte sagen, ob das hier theoretisch korrekt wäre? (mit gcc gehts zumindest)

    Der Unterschied ist hier, dass die Überladung trotzdem existiert. Sofern allerdings für i!=1 sowieso kein f mit nur einem Parameter existieren soll, würde ich das gegenüber enable_if vorziehen, weil es zu einer verständlicheren Fehlermeldung führt.


Anmelden zum Antworten