推论成员函数参数 /返回类型

Deduce member function arguments / return type

本文关键字:返回类型 参数 函数 成员      更新时间:2023-10-16

我有以下代码:

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包含该过程函数的变异参数类型。假定所有过程功能都会返回元组。

我没有得到您想要的,但可能对您有用的东西:

#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的发电机不起作用。

#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;
}

Args1Args2是正确推导的,因为将推导出模板参数列表末尾的包装扩展。传递给foo的成员函数指针包含所有必要类型。foo的所有模板参数将分别推导,然后组合到一定调整后匹配&Generator::process类型的类型。链接

无关:如果未添加进程以返回std::tuple,我们仍然可以使用模板模板参数,又称template <class...> class TT

根据@martin Bonner提供的信息进行编辑

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;
}