Funktionsaufruf abhängig vom typedef eines Parameters



  • Hallo zusammen,

    ich habe eine Template-Funktion, die einen Parameter mit einem bestimmten typedef hat. In dieser Funktion will ich dann je nach Typ des typedefs (eigentlich nur für bestimmte Ausnahmen) den Funktionsaufruf differenzieren.

    als nach folgendem Schema:

    #include <iostream>
    
    template<typename T>
    class Foo{
    public:
    	typedef T type;
    };
    
    template<typename T>
    class Function{
    public:
    	void operator()(){
    		std::cout << "undefined" << std::endl;
    	}
    };
    
    template<>
    class Function<int>{
    public:
    	void operator()(){
    		std::cout << "int" << std::endl;
    	}
    };
    
    template<>
    class Function<void>{
    public:
    	void operator()(){
    		std::cout << "void" << std::endl;
    	}
    };
    
    template<typename T>
    void test(const T& t){
    	typedef typename T::type type;
    	Function<type> func;
    	func();
    	// EDIT: Hier natürlich noch einiges anderes...
    }
    
    int main(){
    	Foo<int> foo1;
    	Foo<void> foo2;
    	Foo<bool> foo3;
    	test(foo1);
    	test(foo2);
    	test(foo3);
    }
    

    int
    void
    undefined

    Der Parameter muss allerdings nicht zwangsläufig ein Foo<...> sein, sondern kann auch ein Bar<...> sein.
    Geht es ohne Verwendung eines Klassen-Template als Hifsmittel?
    Eigentlich bin ich davon überzeugt, dass es nicht anders geht, aber bevor ich zukünftig einen zu umständlichen Weg verwende, wollte ich hier mal nachfragen.

    Gruß,
    XSpille

    EDIT: von mir aus auch eine C++0x-Lösung



  • In deinem Fall könntest du einfach ein Funktionstemplate schreiben und spezialisieren. Allerdings wird das schnell frickelig und ist in den Möglichkeiten begrenzt. Zum Beispiel ist keine partielle Spezialisierung möglich, und die Regeln zur Überladungsauflösung sind nicht intuitiv. Ich bevorzuge deshalb immer Überladung.

    Alexandrescu erklärt in seinem Buch einen genialen Trick:

    // In deiner Metaprogrammierungs-Toolbox
    template <typename T>
    struct Type2Type {};
    

    Angewandt sieht das dann so aus:

    template <typename T>
    void Func(Type2Type<T>)
    {
        std::cout << "undefined" << std::endl;
    }
    
    void Func(Type2Type<int>)
    {
        std::cout << "int" << std::endl;
    }
    
    void Func(Type2Type<void>)
    {
        std::cout << "void" << std::endl;
    }
    
    template<typename T>
    void Test(const T& t)
    {
        Func(Type2Type<typename T::type>());
    }
    


  • Nexus schrieb:

    ...

    I like 👍


Log in to reply