将返回和参数类型从转换运算符提取到函数指针

时间:2016-07-20 09:55:20

标签: c++ templates c++11 c++14

是否可以编写模板来提取类可转换为的函数指针类型的返回类型和参数类型,只知道类本身?例如:

struct Foo {
    using FnPtr = int (*)(char, double);

    operator FnPtr() const { ... }
};

// Can I extract the return type (int) and argument types (char and double),
// knowing only `Foo` as an opaque type?

2 个答案:

答案 0 :(得分:6)

如果Foo没有任何其他转换运算符且没有定义间接运算符,那么您可以依赖*a_foo将提供对所需类型函数的引用这一事实。从那里,你只需要提取返回和参数。

func_ref_traits这里将进行提取:

template <typename Func>
struct func_ref_traits;

template <typename Ret, typename... Args>
struct func_ref_traits<Ret(&)(Args...)> {
    using ret = Ret;
    using args = std::tuple<Args...>;
};

然后conv_func_traits将计算出给定类型的函数类型:

template <typename T>
using conv_func_traits = func_ref_traits<decltype(*std::declval<T>())>;

你会像这样使用它:

conv_func_traits<Foo>::args //std::tuple<char,double>
conv_func_traits<Foo>::ret //int

答案 1 :(得分:3)

你走了:

#include <type_traits>

template <typename...> struct typelist;

template <typename> struct Extract;

template <typename R, typename ...Args>
struct Extract<R(*)(Args...)>
{
  using Result = R;
  using Arguments = typelist<Args...>;
};



template <typename T>
using Return_Type = typename Extract<typename T::FnPtr>::Result;

template <typename T>
using Arguments = typename Extract<typename T::FnPtr>::Arguments;




struct Foo
{
  using FnPtr = int (*)(char, double);
};


int main()
{
  static_assert(std::is_same<Return_Type<Foo>, int>::value, ":(");
  static_assert(std::is_same<Arguments<Foo>, typelist<char, double>>::value, ":(");
}

我使用了一个类型列表来表示参数,如果您更喜欢,可以使用std::tuple。此外,您可能需要更多Extract的专业化来涵盖不同类型的可赎回事物。