使用模板元编程执行重载分辨率 [英] Perform overload resolution with template meta-programming

查看:155
本文介绍了使用模板元编程执行重载分辨率的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

受另一个问题的启发,我试图找到一种方法来推导一个重载成员函数的类型
,给出用于调用
函数的实际参数。这是我到目前为止:

Inspired by another question I tried to find a way to deduce the type of an overload member function given the actual argument used to call that function. Here is what I have so far:

#include <type_traits>

template<typename F, typename Arg>
struct mem_fun_type {
  // perform overload resolution here
  typedef decltype(std::declval<F>()(std::declval<Arg>())) result_type;
  typedef decltype(static_cast<result_type (F::*)(Arg)>(&F::operator())) type;
};

struct foo {};

struct takes_two
{
  void operator()(int);
  void operator()(foo);
};

struct take_one {
  void operator()(float);
};

int main()
{
  static_assert(std::is_same<mem_fun_type<take_one, float>::type, 
                             void (take_one::*)(float)>::value, "Zonk");
  static_assert(std::is_same<mem_fun_type<takes_two, double>::type, 
                             void (takes_two::*)(float)>::value, "Zonk");
  return 0;
}

只要模板参数Arg匹配实际类型
static_cast将成功,但这只是
重载分辨率(完全匹配)的最简单的情况。是否可以在模板元编程中执行
完整的重载解析过程?

As long as the template parameter Arg matches the actual type the static_cast will succeed, but this is only the most trivial case of overload resolution (exact match). Is it possible to perform the complete overload resolution process in template metaprogramming?

这是纯粹的假设,不适用于真实世界。

This is purely hypothetical and not intended for real-world use.

推荐答案

这是最接近我到目前为止:define函数返回不同大小的表,你的结果是 sizeof select(...))接收指针,以便匹配的函数。为了确保代码可以编译,即使函数在给定类中不存在,也可以使用单独的检查 has_function

This is closest I came to it so far: define function returning tables of different sizes and your result is sizeof(select(...)) receiving pointer to function you want to match. To ensure that the code will compile even if function does not exist in given class, you can use separate check has_function.

重载解析的结果在中选择< has_function< T> :: value,T> :: value

使用这个代码你甚至可以解析数据成员,而不只是函数,这只是一个问题,为选择函数正确的参数。

With this code you can even "resolve" data members, not just functions, it's only a question of making right parameter for select function.

但是有一个缺陷这里 - 重载分辨率不在功能参数,而是在功能类型。

However there is one deficiency here - overload resolution is not on function parameters, but on function type. Meaning none of usual parameter type conversions takes place.

  // Verify the name is valid
  template <typename T>
  struct has_function
  {
    struct F {int function;};
    struct D : T, F {};
    template <typename U, U> struct same_;
    template <typename C> static char(&select_(same_<int F::*, &C::function>*))[1];
    template <typename> static char(&select_(...))[2];
    enum {value = sizeof(select_<D>(0)) == 2};
  };

  // Values to report overload results
  enum type { none=1 , function_sz_size_t , function_sz , function_string };

  template <bool, typename R> struct select;

  template <typename R> struct select<false, R>
  {
    enum {value = none};
  };

  template <typename R> struct select<true, R>
  {
    // Define your overloads here, they don't have to be templates.
    template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(const char*, Arg)))[function_sz_size_t];
    template <typename Ret, typename Arg> static char(&select_(Ret (R::*)(Arg)))[function_sz];
    template <typename Ret> static char(&select_(Ret (R::*)(std::string)))[function_string];
    template <typename Ret> static char(&select_(Ret (R::*)(std::string&&)))[function_string];
    template <typename Ret> static char(&select_(Ret (R::*)(const std::string&)))[function_string];
    static char(&select_(...))[none];
    enum {value = sizeof(select_(&R::function))};
  };

这篇关于使用模板元编程执行重载分辨率的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆