使用从外部参数包中获取的参数类型声明一个函数
Declaring a function with types of arguments taken from a foreign parameter pack
假设我有某种类型列表
template<typename... Types> struct TypeList {};
现在在其他一些 class 中,我可以通过多种方式生成这样的 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*)
待申报。
您可以从实现该方法的基础 class 派生:
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;
// ...
};
您可以使用 static_assert
和 std::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);
}
假设我有某种类型列表
template<typename... Types> struct TypeList {};
现在在其他一些 class 中,我可以通过多种方式生成这样的 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*)
待申报。
您可以从实现该方法的基础 class 派生:
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;
// ...
};
您可以使用 static_assert
和 std::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);
}