Есть ли reference_wrapper <> для ссылок rvalue?

Интересно, как можно сделать следующее

void f(string &&s) { 
  std::string i(move(s)); 
  /* other stuff */ 
} 

int main() { 
  std::string s; 
  bind(f, s)(); // Error.
  bind(f, move(s))(); // Error.
  bind(f, ref(s))(); // Error.
}

Как я могу передать ссылку на rvalue и сохранить ее как ссылку rvalue (возможно, обернутую) в вызове обертка? Я знаю, что могу вручную написать класс вроде std :: reference_wrapper <> , у которого есть функция преобразования в T && , но я бы предпочел избежать этого и использовать стандартную технологию.


Я реализовал это так, как рекомендует AProgrammer:

template<typename T> struct adv { 
  T t; 
  explicit adv(T &&t):t(forward<T>(t)) {} 
  template<typename ...U> T &&operator()(U &&...) { 
    return forward<T>(t); 
  } 
}; 

template<typename T> adv<T> make_adv(T &&t) { 
  return adv<T>{forward<T>(t)}; 
}

namespace std { 
  template<typename T> 
  struct is_bind_expression< adv<T> > : std::true_type {}; 
} 

Теперь я могу сказать

void f(string &&s) { 
  std::string i(move(s)); 
  /* other stuff */ 
} 

int main() { 
  std::string s; 
  bind(f, make_adv(move(s)))(); // Works!
}

Если мы передадим lvalue в make_adv , он перешлет его как lvalue, относящийся к входному аргументу, чтобы он мог в этом случае используется вместо std :: ref .

13
задан Johannes Schaub - litb 3 October 2011 в 13:13
поделиться