Я смотрел Скотта Мейерса поговорим об универсальных справочниках с конференции 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