我有以下代码:
template <class... Args>
struct TypeList
{
static constexpr size_t size = sizeof...(Args);
template <std::size_t N>
using type = typename std::tuple_element<N, std::tuple<Args...>>::type;
};
struct Generator
{
std::tuple<float, float> process(float, int, size_t)
{
return std::make_tuple(0.0f, 1.0f);
}
};
是否有任何方法可以推导出元组模板参数以及Generator::process
的输入参数,以便构造具有以下模板参数的类。
struct Node<GenType, ReturnTypesList, ArgumentTypeList>
其中ReturnTypesList
包含返回元组的模板参数,ArgumentTypeList
包含过程函数的可变参数类型。假设所有过程函数都将返回一个元组。
答案 0 :(得分:0)
我没有得到你想要的东西,但可能这样的东西对你有用:
#include <type_traits>
#include <tuple>
template <class... Args>
struct TypeList
{
static constexpr size_t size = sizeof...(Args);
template <std::size_t N>
using type = typename std::tuple_element<N, std::tuple<Args...>>::type;
};
struct Generator
{
std::tuple<float, float> process(float, int, size_t)
{
return std::make_tuple(0.0f, 1.0f);
}
};
template<typename GenType, typename ReturnTypesList, typename ArgumentTypeList>
struct Node {};
template<typename T>
struct S
{
template<typename... RArgs, typename... Args>
static auto gen(std::tuple<RArgs...>(T::*)(Args...)) -> Node<T, TypeList<RArgs...>, TypeList<Args...>>;
};
template<typename T>
using NodeType = decltype(S<T>::gen(&T::process));
int main()
{
static_assert(std::is_same<NodeType<Generator>, Node<Generator, TypeList<float, float>, TypeList<float, int, size_t>>>::value, "!");
}
NodeType
是专门针对特定生成器的必需类型,您可以从main
中的测试中看到。
在具体案例中:
Node<Generator, TypeList<float, float>, TypeList<float, int, size_t>>
不介意成员是作为函数参数而不是模板参数提供的。无论如何,整个过程在编译时已解决。
作为旁注,该解决方案不适用于那些过载process
的生成器。
答案 1 :(得分:-1)
#include <tuple>
template <class...>
struct Node;
struct Generator {
std::tuple<float, float> process(float, int, size_t);
};
template <class... Args1, class ClassType, class... Args2>
auto foo(std::tuple<Args1...> (ClassType::*)(Args2...)) -> Node<ClassType, Args1..., Args2...>;
int main() {
// T is Node<Generator, float, float, float, int, size_t>
using T = decltype(foo(&Generator::process));
return 0;
}
正确推导出 Args1
和Args2
,因为将推断出模板参数列表最后出现的包扩展。传递给foo
的成员函数指针包含所有必需的类型。 foo
的所有模板参数将单独推导,然后在特定调整后合并为与&Generator::process
类型匹配的类型。 Link
不相关:如果流程尚未返回std::tuple
,我们仍然可以使用模板模板参数,即template <class...> class TT
template <class...>
struct Node {};
template <class...>
struct TypeList {};
struct Generator {
std::tuple<float, float> process(float, int, size_t) {}
};
template <class... ReturnArgs, class GeneratorType, class... Args>
auto magic(std::tuple<ReturnArgs...> (GeneratorType::*arg)(Args...))
-> Node<GeneratorType, TypeList<ReturnArgs...>, TypeList<Args...> > {
using ReturnType =
Node<GeneratorType, TypeList<ReturnArgs...>, TypeList<Args...> >;
return ReturnType{};
}
int main() {
magic(&Generator::process);
return 0;
}