на основе @ songyuanyao-х Answer, я заметил, что моя ошибка проверял неправильную вещь: Мое намерение состояло в том, чтобы проверить, будет ли результат i+j
связываться с ссылкой rvalue, но я проверил, is a rvalue reference.
decltype выводит тип, основанный на value category, не основаны на том, что reference type значение будет связываются с:
1), если значение категории выражения xvalue
, то decltype урожаи T&&
;
2) если категория значений выражения равна lvalue
, тогда decltype дает T&
;
3) если категория значений выражения равна prvalue
, тогда decltype дает T
.
Как показано в списке, поскольку C++ 11, rvalues
не существует в качестве отдельной категории на самом низком уровне. Теперь они представляют собой составную категорию, содержащую как prvalues
, так и xvalues
. Вопрос, как написано, спрашивает, является ли выражение rvalue reference
и проверяет, является ли оно xvalue
.
Из вышеприведенного списка ясно, что i+j
является prvalue
, поэтому применяется третий случай. Это объясняет, почему decltype(i + j)
является int
, а не int&&
. Оба xvalues
и prvalues
связывать с ссылки rvalue.
Так, проверяя, связывается ли i+j
к lvalue reference
или rvalue reference
подтверждает, что, действительно, связывается сrvalue reference
:
void foo(const int& f)
{
std::cout << "binds to lvalue reference" << std::endl;
}
void foo(int&& f)
{
std::cout << "binds to rvalue reference" << std::endl;
}
void test(int i, int j)
{
foo(i); // lvalue -> lvalue ref
foo(std::move(i)); // xvalue -> rvalue ref
// (std::move converts the argument to a rvalue reference and returns it as an xvalue)
foo(i + j); // prvalue -> rvalue ref
}
В заключение:i+j
является не ссылка Rvalue , но он привязывается к.
Это просто простые старые данные. Я не думаю, что вы можете std :: move a int .. – 0xbaadf00d
Это всегда было int, с незапамятных времен (a.k.a. первые Unixes). Как бы вы переместили '2 + 2'? – bipll
Вы можете очень много 'std :: move' a' int', и это в любом случае, кроме того, OP спрашивает о категории значений 'i + j'. –