Идеальная пересылка члена объекта - PullRequest
15 голосов
/ 20 декабря 2011

Предположим, у меня есть два struct s:

struct X {};
struct Y { X x; }

У меня есть функции:

void f(X&);
void f(X&&);

Как мне написать функцию g(), которая принимает Y& или Y&&, но безупречная пересылка X& или X&& до f() соответственно:

template <typename T>
void g(T&& t) {
  if (is_lvalue_reference<T>::value) {
    f(t.x);
  } else {
    f(move(t.x));
  }
}

Приведенный выше код иллюстрирует мое намерение, но не очень масштабируется по мере увеличения количества параметров.Есть ли способ заставить его работать для идеальной пересылки и сделать его масштабируемым?

Ответы [ 2 ]

21 голосов
/ 23 декабря 2011
template <typename T>
void g(T&& t) {
  f(std::forward<T>(t).x);
}
3 голосов
/ 20 декабря 2011

Я думаю, что это будет работать, хотя я не уверен:

template<class T, class M>
struct mforward {
  using type = M&&; 
};
template<class T, class M>
struct mforward<T&, M> {
  using type = M&; 
};

template <typename T>
void g(T&& t) {
  f(std::forward<typename mforward<T, decltype(t.x)>::type>(t.x));
}
...