Как копировать из переменных примитивного типа при передаче через аргументы ссылочной функции rvalue

Я могу скопировать из переменной не примитивного типа с помощью конструктора копирования и передать ее через аргумент ссылочной функции rvalue.

Но как это сделать с переменными примитивного типа?

например:

#include <cassert>
#include <iostream>
struct MyClass
{
int m = 0;
};
MyClass& f(MyClass& x)
{
x.m++;
return x;
}
inline MyClass f(MyClass&& x)
{
return f(x);
}
int& f(int& x)
{
x++;
return x;
}
inline int f(int&& x)
{
return f(x);
}
int main()
{
MyClass x1;
auto y1 = f(MyClass(x1)); // Calls f(MyClass&&)
// Result: x1.m = 0, y1.m = 1

int x2 = 0;
auto y2 = f(int(x2)); // Calls f(int&)
// Result: x2 = 1, y2 = 1

std::cout << x1.m << x2; // Result in VS2013: '01' But '00' in gcc and clang!
assert(x1.m == x2); // FAILED in VS2013!!!
return 0;
}

Результат в Visual Studio 2013 — «01» с ошибкой подтверждения.

http://rextester.com/CAPY87169

1

Решение

Ваш код верен, и это похоже на ошибку в VS2013.

Проще MCVE:

#include <iostream>

void f(int& x)  { std::cout << "f(lv)\n"; }
void f(int&& x) { std::cout << "f(rv)\n"; }

int main()
{
int x2 = 0;
f( int(x2) );
f( (int)x2 );
}

Выход должен быть:

f(rv)
f(rv)

MSVC онлайн тестер

Обратите внимание, что дальнейшее тестирование показывает, что ошибка действительно (int)x2 MSVC считается lvalue; Это не ошибка в расширении MSVC, которое позволяет привязывать rvalues ​​к ссылкам lvalue (так как ссылка на rvalue в любом случае лучше соответствует).

Вы можете исправить это, используя /Za переключатель.


Выражение int(x2) покрывается C ++ 14 [expr.type.conv] / 2 (C ++ 11 имеет такую ​​же нумерацию):

спецификатор простого типа (7.1.6.2) или же спецификатор typename (14.6) с последующим в скобках список_выражений создает значение указанного типа с учетом списка выражений. Если список выражений является одним выражением, выражение преобразования типа эквивалентно (в определенности и если определено в значении) соответствующему приведенному выражению (5.4).

Соответствующее приведенное выражение:

Результат выражения (T) cast-expression имеет тип T. Результатом является lvalue, если T является ссылочным типом lvalue или ссылкой rvalue на тип функции, и xvalue, если T является ссылкой rvalue на тип объекта; в противном случае результат является prvalue.

3

Другие решения


По вопросам рекламы [email protected]