How to copy from primitive type variables when passing through rvalue reference function arguments

妖精的绣舞 提交于 2019-12-11 13:28:22

问题


I can copy from a non-primitive type variable by copy constructor and pass it through rvalue reference function argument.

But how can do this with primitive type variables?

for example:

#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;
}

The result in Visual Studio 2013 is '01' with assertion failed.

http://rextester.com/CAPY87169


回答1:


Your code is correct and this seems to be a bug in VS2013.

Simpler 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 );
}

Output should be:

f(rv)
f(rv)

MSVC online tester

Note that further testing shows that the bug is really that (int)x2 is treated as an lvalue by MSVC; it's not a bug with MSVC's extension to allow rvalues to bind to lvalue references (since the rvalue reference is a better match anyway).

You may be able to fix this by using the /Za switch.


The expression int(x2) is covered by C++14 [expr.type.conv]/2 (C++11 has the same numbering):

A simple-type-specifier (7.1.6.2) or typename-specifier (14.6) followed by a parenthesized expression-list constructs a value of the specified type given the expression list. If the expression list is a single expression, the type conversion expression is equivalent (in definedness, and if defined in meaning) to the corresponding cast expression (5.4).

The corresponding cast expression is:

The result of the expression (T) cast-expression is of type T. The result is an lvalue if T is an lvalue reference type or an rvalue reference to function type and an xvalue if T is an rvalue reference to object type; otherwise the result is a prvalue.



来源:https://stackoverflow.com/questions/26480413/how-to-copy-from-primitive-type-variables-when-passing-through-rvalue-reference

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!