简体   繁体   English

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

[英]Deduce member function arguments / return type

I have the following code: 我有以下代码:

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

Is there any way to deduce both the tuple template arguments as well as the input arguments for Generator::process in order to construct a class that has the following template arguments. 是否有任何方法可以推导出Generator::process的元组模板参数和输入参数,以构造具有以下模板参数的类。

struct Node<GenType, ReturnTypesList, ArgumentTypeList>

Where ReturnTypesList contains template arguments of the returned tuple and ArgumentTypeList contains the variadic argument types of the process function. 其中ReturnTypesList包含返回的元组的模板参数,而ArgumentTypeList包含流程函数的可变参数类型。 It is assumed that all process functions will return a tuple. 假定所有过程函数都将返回一个元组。

I didn't get exactly what you are looking for, but probably something like this would work for you: 我没有完全找到您想要的东西,但是可能这样的事情对您有用:

#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 is the required type once specialized with the specific generator, as you can see from the test in the main . NodeType是曾经专门与特定的发电机,你可以从测试看到所需的类型main
In the specific case: 在特定情况下:

Node<Generator, TypeList<float, float>, TypeList<float, int, size_t>>

Don't mind if the member is provided as a function parameter instead of a template argument. 不必介意该成员是否作为函数参数而不是模板参数提供。 The whole thing is solved at compile-time anyway. 整个问题还是在编译时解决了。

As a side note, the solution won't work for those generators that have overloaded process . 附带说明一下,该解决方案不适用于那些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;
}

Args1 and Args2 are deduced properly because the pack expansion that appears at the very end of the template parameter list will be deduced. 可以正确推导Args1Args2 ,因为Args2导出现在模板参数列表末尾的装箱扩展。 And the member function pointer which is passed to foo contains all the types necessary. 传递给foo的成员函数指针包含所有必需的类型。 All the template parameters of foo will be deduced separately and then combined to a type which match the type of &Generator::process after certain adjustment. foo所有模板参数将分别推导,然后在经过一定的调整后组合为&Generator::process类型匹配的类型。 Link 链接

Unrelated: If process isn't garanted to return a std::tuple , we can still use a template template parameter, aka template <class...> class TT 不相关:如果进程不被授权返回std::tuple ,我们仍然可以使用模板模板参数,也称为template <class...> class TT

Edit according to the information provided by @Martin Bonner 根据@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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM