将调用转发到成员方法的模板

Template forwarding calls to a member's method

本文关键字:成员方法 调用 转发      更新时间:2023-10-16

考虑以下内容:

template <typename type> class my_wrapper
{
  type _;
  template <typename... types, typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types...> :: value> :: type * = nullptr> void my_method(types... items)
  {
    _.my_method(items...);
  }
};

其中,正如您所想象的,has_my_method_callable_with_the_following_types是某种SFINAE结构,它允许我确定type是否有一个可以用这些类型调用的方法。

正如您很容易看到的,上面的示例基本上将所有对my_method的调用向下转发到_。嗯几乎所有。如果我这样做会发生什么:

class my_type
{
  void my_method(int & x)
  {
    x++;
  }
};
my_wrapper <my_type> my_wrapped;
int x;
my_wrapped.my_method(x);

显然,上面的方法不起作用,因为x将通过复制传递给函数,而my_type :: my_method通过引用接受它。所以我想知道:有没有办法解决这个问题?我当然可以:

template <typename... types, typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types & ...> :: value> :: type * = nullptr> void my_method(types & ... items)
{
  _.my_method(items...);
}

但对称地说,当我传递int文字时,我会遇到问题,比如说,我不能通过引用来获得这些文字,但一些my_type :: my_method(int x)完全可以接受这些文字。

我该如何解决这个问题?我想将所有到my_wrapper <type> :: my_method的呼叫无缝地转发到type :: my_method

海盗小心:我不能使用继承,所以请不要建议!:(

这正是为引入完美转发和转发参考的原因

template <
  typename... types,
  typename std :: enable_if <has_my_method_callable_with_the_following_types <type, types...> :: value> :: type * = nullptr
> void my_method(types&&... items)
{
  _.my_method(std::forward<types>(items)...);
}

工作原理:

该语言中有一条特殊规则,即当推导T&&结构中的T时,并且用于推导的自变量是类型为U的左值,则T被推导为U&而不是U

净效应是,当一个参数是转发引用(对于推导的TT&&(时,它要么是左值引用(如果该参数是左值(,要么是右值引用(若该参数是右值(。std::forward<T>随后将根据需要将其强制转换回左值或右值。