模板转发对成员方法的调用

Template forwarding calls to a member's method

考虑以下几点:

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

最终效果是,当参数是转发引用时(T&& 推导出 T),它将是左值引用(如果参数是左值),或者右值引用(如果参数是右值)。 std::forward<T> 然后会根据需要将其转换回左值或右值。