如何获取模板参数包以推断按引用传递而不是按值传递?

sh1*_*sh1 1 c++ pass-by-reference variadic-templates c++14

在下面的类中,wrapper获取指向任意const方法的指针,并返回对const已删除的方法的调用结果.这可以用来生成相应的非const方法......

struct C {
  int x[10];

  int const& get(int i) const { return x[i]; }
  int const& getr(int const& i) const { return x[i]; }

  template<typename T, typename... Ts>
  auto& wrapper(T const& (C::*f)(Ts...) const, Ts... args) {
    return const_cast<T&>((this->*f)(args...));
  }

  int& get(int i) { return wrapper(&C::get, i); }
  int& getr(int const& i) { return wrapper(&C::getr, i); }
};
Run Code Online (Sandbox Code Playgroud)

几乎.

问题是最终方法getr()无法编译,因为传递给的参数列表wrapper()并不意味着传递引用.当我们进入内部时wrapper(),编译器正在寻找一个按值传递的版本getr().

这有诀窍吗?

Tar*_*ama 6

您可以完美地转发函数的参数:

template<typename T, typename... Ts, typename... Args>
auto& wrapper(T const& (C::*f)(Ts...) const, Args&&... args) {
  return const_cast<T&>((this->*f)(std::forward<Args>(args)...));
}
Run Code Online (Sandbox Code Playgroud)

这是通过制作args转发参考参数包来实现的.请注意,我们需要引入一个新的Args模板参数包,以便正确推导出参数.