Я смотрел Скотта Мейерса поговорим об универсальных справочниках с конференции C ++ and Beyond 2012, и пока все имеет смысл. Однако примерно через 50 минут один из зрителей задает вопрос, который меня тоже интересовал. Мейерс говорит, что его не волнует ответ, потому что он не-идиоматичен и может ввести его в заблуждение, но мне все равно интересно.
Представленный код выглядит следующим образом:
// Typical function bodies with overloading:
void doWork(const Widget& param) // copy
{
// ops and exprs using param
}
void doWork(Widget&& param) // move
{
// ops and exprs using std::move(param)
}
// Typical function implementations with universal reference:
template <typename T>
void doWork(T&& param) // forward => copy and move
{
// ops and exprs using std::forward<T>(param)
}
Дело в том, что когда мы берем ссылку на rvalue, мы знаем, что у нас есть rvalue, поэтому мы должны std::move
сохранить тот факт, что это rvalue. Когда мы берем универсальную ссылку (T&&
, где T
- выведенный тип), мы хотим, чтобы std::forward
сохранил тот факт, что это могло быть lvalue или rvalue.
Итак, вопрос: поскольку std::forward
сохраняет, было ли значение, переданное в функцию, lvalue или rvalue, а std::move
просто приводит свой аргумент к rvalue, можем ли мы просто использовать std::forward
везде? Будет ли std::forward
вести себя как std::move
во всех случаях, когда мы будем использовать std::move
, или есть какие-то важные различия в поведении, которые не учитываются обобщением Мейерса?
Я не предлагаю, чтобы кто-то это делал, потому что, как правильно говорит Мейерс, это совершенно не идиоматично, но следующее также допустимое использование std::move
:
void doWork(Widget&& param) // move
{
// ops and exprs using std::forward<Widget>(param)
}
std::forward(lvalue_expression)
выдаст lvalue, если типlvalue_expression
является lvalue, и даст rvalue, если типlvalue_expression
является rvalue (например, в случае именованного rvalue). Здесь я используюstd::forward
для выражения, которое, как мне известно, имеет тип rvalue. - person Joseph Mansfield   schedule 04.11.2012std::forward
в том, что он иногда может изменять lvalue на rvalue. - person Mankarse   schedule 04.11.2012