[C++0x] BaseTemplate<Args...> make_var(Args &&... in) - wie geht das?



  • 314159265358979 schrieb:

    wxSkip schrieb:

    Könnte man jetzt auch noch make_var<Printer, true, false, 5>(1, 7) schreiben, was dann einen Printer<true, false, 5, int, int>(1,7) zurückgibt?
    template<typename... Types> Types... template_values funktioniert schon einmal nicht.

    Du müsstest für jede Anzahl an Compiletime-Argumenten eine Überladung schreiben, da man nicht mehr als 1 typename... in einem template haben kann.

    Könnte man dann eine Ersatzlösung wie make_var<Printer, ValueHolder<true, false, 5> >(1, 7) verwenden? Konkret geht es mir um die Implementierung von ValueHolder bzw. wie kann ich es vermeiden TypeHolder<bool, bool, int>::ValueHolder<true, false, 5> schreiben zu müssen?

    EDIT: Einfacher wäre wohl ValueHolder<true, false, 5>::make_var<Printer>(1, 7) . Das ändert allerdings nichts am Problem der impliziten Typerkennung bei Template-Wert-Argumenten.



  • Ich muss mich selbst korrigieren, nicht mal mit Überladung ist das lösbar. Zu deinem Edit: Muss ich mal nachdenken und evtl das heilige IRC befragen.



  • 314159265358979 schrieb:

    Ich muss mich selbst korrigieren, nicht mal mit Überladung ist das lösbar. Zu deinem Edit: Muss ich mal nachdenken und evtl das heilige IRC befragen.

    Was ist denn das IRC? Wenn ich danach suche, finde ich bloß den hiesigen Foren-Channel...



  • Internet Relay Chat 😉



  • Das zweite ist auch nicht möglich, aus dem selben Grund wie das erste - Du kannst kein template machen, das beliebige Compiletime-Werte schluckt.



  • 314159265358979 schrieb:

    Das zweite ist auch nicht möglich, aus dem selben Grund wie das erste - Du kannst kein template machen, das beliebige Compiletime-Werte schluckt.

    Ich habe schon versucht, den zusätzlichen Schreibaufwand bei der TypeHolder-Variante durch ein Makro mit decltype() und einer Funktion, die den TypeHolder-Typ zurückliefert, zu umgehen, aber dann kam ich auf Fehler bei Join bei typedef T<values..., Args...> type; (der Bug) und template<ValueTypes..., typename...> class T (anderer Fehler), sodass ich es jetzt mit einer für mich verwendbaren Alternative (die IMHO beim Aufruf auch schöner aussieht) versuche:

    template<bool b1, int i1> class Holder
    {
        public:
        template<typename T1, typename T2> class Printer
        {
            public:
            Printer(T1 t1, T2 t2)
            {
                std::cout << b1 << " " << i1 << " " << t1 << " " << t2 << "\n";
            }
        };
    };
    
    template<template<typename...> class T, typename... Args>
    struct Join
    {
        typedef T<Args...> type;
    };
    
    template <template<typename...> class T, typename... Args>
    static typename Join<T, typename std::decay<Args>::type...>::type
        make_var(Args&&... args)
    {
        return typename Join<T, typename std::decay<Args>::type...>::type(std::forward<Args>(args)...);
    }
    
    int main()
    {
        auto var = make_var<Holder<true, 5>::Printer>(5, 6);
    }
    


  • Vielleicht wäre ja das hier etwas für dich:

    template <bool b, int i, typename T0, typename T1>
    struct printer
    {
        printer(T0 t0, T1 t1)
        {
            std::cout << t0 << b << t1 << i;
        }
    };
    
    template
    <
        template <bool, int, typename...> class T,
        bool B,
        int I,
        typename... Args
    >
    struct join
    {
        typedef T<B, I, Args...> type;
    };
    
    template <bool B, int I, typename... Args>
    typename join<printer, B, I, typename std::decay<Args>::type...>::type make_printer(Args&&... args)
    {
        return typename join<printer, B, I, typename std::decay<Args>::type...>::type(std::forward<Args>(args)...);
    }
    

    Der Aufruf sieht dann einfach so aus:

    make_printer<true, 42>(3.14, 666);
    

    Hier sind allerdings die ersten beiden Template-Parameter immer bool und int.



  • 314159265358979 schrieb:

    Vielleicht wäre ja das hier etwas für dich:

    template <bool b, int i, typename T0, typename T1>
    struct printer
    {
        printer(T0 t0, T1 t1)
        {
            std::cout << t0 << b << t1 << i;
        }
    };
     
    template
    <
        template <bool, int, typename...> class T,
        bool B,
        int I,
        typename... Args
    >
    struct join
    {
        typedef T<B, I, Args...> type;
    };
     
    template <bool B, int I, typename... Args>
    typename join<printer, B, I, typename std::decay<Args>::type...>::type make_printer(Args&&... args)
    {
        return typename join<printer, B, I, typename std::decay<Args>::type...>::type(std::forward<Args>(args)...);
    }
    

    Der Aufruf sieht dann einfach so aus:

    make_printer<true, 42>(3.14, 666);
    

    Hier sind allerdings die ersten beiden Template-Parameter immer bool und int.

    Danke, aber ich brauche es dynamisch (sowohl für das Basis-Template als auch für die Werte).



  • Muss denn die Anzahl an möglichen Compile-Time Argumenten auch variabel sein oder sind es immer nur 2?


  • Mod

    wxSkip schrieb:

    Danke, aber ich brauche es dynamisch (sowohl für das Basis-Template als auch für die Werte).

    Wie dynamisch? Wenn B und I nicht beim Compilieren bekannt sind, können sie keine Templateparameter sein.



  • camper schrieb:

    wxSkip schrieb:

    Danke, aber ich brauche es dynamisch (sowohl für das Basis-Template als auch für die Werte).

    Wie dynamisch? Wenn B und I nicht beim Compilieren bekannt sind, können sie keine Templateparameter sein.

    Ich meinte, die Anzahl und die Typen sollen dynamisch, also Compiletime-Abhängig und nicht hardgecoded sein.


Anmelden zum Antworten