Restrict variadic template arguments

前端 未结 5 775
旧时难觅i
旧时难觅i 2020-12-02 08:58

Can we restrict variadic template arguments to a certain type? I.e., achieve something like this (not real C++ of course):

struct X {};

auto foo(X... args)
         


        
5条回答
  •  囚心锁ツ
    2020-12-02 09:21

    C++14

    Since C++14 you can use also variable template, partial specialization and static_assert to do that. As an example:

    #include 
    
    template class, typename...>
    constexpr bool check = true;
    
    template class C, typename U, typename T, typename... O>
    constexpr bool check = C::value && check;
    
    template
    void f() {
        // use std::is_convertible or whichever is the best trait for your check
        static_assert(check, "!");
        // ...
    }
    
    struct S {};
    
    int main() {
        f();
        // this won't work, for S is not convertible to int
        // f();
    }
    

    You can also use check in conjunction with std::enable_if_t as a return type, if you don't want to use static_assert for some unknown reasons:

    template
    std::enable_if_t>
    f() {
        // ...
    }
    

    And so on...

    C++11

    In C++11, you can also design a solution that stops the recursion immediately when a type that is not to be accepted is encountered. As an example:

    #include 
    
    template struct check;
    template struct check: std::false_type {};
    template struct check: check {};
    template<> struct check<>: std::true_type {};
    
    template
    void f() {
        // use std::is_convertible or whichever is the best trait for your check
        static_assert(check::value...>::value, "!");
        // ...
    }
    
    struct S {};
    
    int main() {
        f();
        // this won't work, for S is not convertible to int
        // f();
    }
    

    As mentioned above, you can use check also in the return type or wherever you want.

提交回复
热议问题