简体   繁体   中英

How do I get a template parameter pack to infer pass-by-reference rather than pass-by-value?

In the following class, wrapper takes a pointer to an arbitrary const method and returns the result of a call to that method with const removed. This can be used to generate the corresponding non- const method...

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); }
};

almost.

The problem is that the final method getr() cannot be compiled, because the argument list passed to wrapper() doesn't imply pass-by-reference. By the time we get inside wrapper() the compiler is looking for a pass-by-value version of getr() .

Is there a trick to this?

You can perfect forward the arguments to the function:

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)...));
}

This is achieved by making args a forwarding reference parameter pack. Note that we need to introduce a new Args template parameter pack in order to deduce the arguments correctly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM