SFINAE in Konstruktor mit Variadischem Template



  • Hi

    Es gibt ja diesen Trick, dass man SFINAE in Konstruktoren kriegt mittels Dummy-Parametern, da Konstruktoren keinen Rückgabetyp haben.

    #include <iostream>
    #include <type_traits>
    
    struct foo
    {
        template<typename T>
        foo(T, std::enable_if_t<std::is_same_v<T, int>>* =0)
        {
            std::cout << "1\n";
        }
        template<typename T>
        foo(T, std::enable_if_t<!std::is_same_v<T, int>>* =0)
        {
            std::cout << "2\n";
        }
    };
    
    int main()
    {
        foo a{1};
        foo b{1u};
    }
    

    Ich frage mich gerade, wie ich das bewerkstelligen soll für einen Variadic Template Konstruktor:

    struct foo
    {
        template<typename... T>
        foo(T&&..., std::enable_if_t<(std::is_same_v<T, int> && ...)>* =0)
        {
            std::cout << "1\n";
        }
    };
    

    Das geht ja nicht, weil Parameter Packs das letzte Argument sein müssen.

    Jemand 'ne Idee?


  • Mod

    Defaulttemplateparameter:

    struct foo
    {
        template<typename... T, std::enable_if_t<(std::is_same_v<T, int> && ...), int> =0>
        foo(T&&...)
        {
            std::cout << "1\n";
        }
    };
    

  • Mod

    Sauberer wird es letztlich mit Concepts werden (GCC -fconcepts ):

    struct foo 
    { 
        template<typename... T> 
        foo(T&&...) requires (std::is_same_v<T, int> && ...)
        { 
            std::cout << "1\n"; 
        } 
    };
    

    Allerdings ist deine Idee sowieso fragwürdig. Du unterbindest bspw. implizite Konvertierungen von anderen Typen, auch arithmetischen. Was spricht gegen eine initializer_list<int> ?


Anmelden zum Antworten