声明一个函数,其中包含从外部参数包中获取的参数类型

时间:2016-06-07 21:19:36

标签: c++ c++11 variadic-templates

假设我有某种类型列表

template<typename... Types> struct TypeList {};

现在在其他一些课程中,我可以通过各种方式生成这样的TypeList

template<class T> struct MyClass {
    using MyList = TypeList<T, typename Something<T>::type, SomethingElse>;
    // ...
};

如何声明一个方法,其中包含从此类型列表中提取的参数类型?例如,如果我设置MyList = TypeList<int, float, const char*>,我希望方法

void my_method(int, float, const char*)

宣布。

2 个答案:

答案 0 :(得分:4)

您可以从实现该方法的基类派生:

template <typename> struct MethodProvider;

template <typename ...Args>
struct MethodProvider<TypeList<Args...>>
{
    void my_method(Args ...args);
};

template <typename T>
struct MyClassAux
{
    using MyList = TypeList<T, typename Something<T>::type, SomethingElse>;
};

template <typename T>
struct MyClass
    : private MyClassAux<T>
    , private MethodProvider<typename MyClassAux<T>::MyList>
{
    using typename MyClassAux<T>::MyList;
    using MethodProvider<typename MyClassAux<T>::MyList>::my_method;

    // ...
};

答案 1 :(得分:0)

您可以使用static_assertstd::is_same约束my_method的参数

#include <iostream>
#include <string>
#include <vector>
#include <type_traits>

template<typename... Types> struct TypeList {};

template<class T> struct MyClass {
    using MyList = TypeList<int, T>;

    template<typename ...Args>
    void my_method(Args ...args) {
        static_assert(std::is_same<MyList, TypeList<Args...>>::value, "invalid arguments");
        auto dummy = {(std::cout << args << "\n", 0)...};
        (void)(dummy); // avoid variable warning
    }
};

int main()
{
    MyClass<float> c;
    c.my_method(1, 2.3f);
//    c.my_method(1, ""); // unmatched arguments won't compile
//    c.my_method(1);
}

Online Demo