Expansion Loci: Dependent Template für jedes Element aus Parameter Pack aufrufen?



  • Hallo

    Mein Problem lässt sich mit Code einfacher beschreiben als mit Worten.

    #include <iostream>
    #include <typeinfo>
    
    using namespace std;
    
    template<typename... T>
    class test_loci
    {
        template<typename U>
        void dependent()
        {
            cout << typeid(U).name() << endl;
        }
    public:
        test_loci()
        {
            dependent<T>()...;
        }
    };
    
    int main()
    {
        test_loci<int, bool, void> test;
        (void)test;
    }
    

    Ziel ist es, dass die Template-Funktion dependent<U> für jedes T für die Instanzierung von Template test_loci einmal aufgerufen wird.

    Im konkreten Beispiel also für int, bool und void. Jedoch bekomme ich hier diverse Fehler "missing ';' before '...'" und "'T': parameter pack must be expanded in this context".

    Wie schreibe ich das richtig? Ich weiss es muss irgendwie gehen.

    $Edit: Warum funktioniert dies???

    #include <iostream>
    #include <typeinfo>
    
    using namespace std;
    
    template<typename... T>
    class test_loci
    {
        template<typename U>
        int dependent(int x)
        {
            cout << typeid(U).name() << endl;
            return x;
        }
    public:
        test_loci()
        {
            static int y[] = { dependent<T>(2)... };
            (void)y;
        }
    };
    
    int main()
    {
        test_loci<int, bool, void> test;
        (void)test;
    }
    

  • Mod

    Eine Packexpansion ist nur in bestimmten Kontexten möglich. Insbesondere ist vor C++17 das Resultat einer Expansion niemals ein einfacher Ausdruck sondern immer eine Liste und kann als solche in einem Statement nicht allein stehen.
    In C++17 geht:

    test_loci()
        {
            (...,dependent<T>());
        }
    
    static int y[] = { dependent<T>(2)... };
    

    Das funktioniert, weil die Expansion hier eine Initialisierungsliste ist - das ist ein zulässiger Kontext.



  • Hi camper

    D.h. ich kann vor C++17 nur die Variante mit der Initialisierung benutzen, wenn ich sowas machen will. Das ist nicht elegant, aber damit kann ich leben.

    Vielen Dank!


Log in to reply