[英]How to copy from primitive type variables when passing through rvalue reference function arguments
我可以通过复制构造函数从非原始类型变量复制并通过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”,断言失败。
你的代码是正确的,这似乎是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)
请注意,进一步测试表明该错误实际上是(int)x2
被MSVC视为左值; 这不是MSVC扩展允许rvalues绑定到左值引用的错误(因为rvalue引用无论如何都是更好的匹配)。
您可以使用/Za
开关来解决此问题。
表达式int(x2)
由C ++ 14 [expr.type.conv] / 2覆盖(C ++ 11具有相同的编号):
简单类型说明符(7.1.6.2)或类型名称说明 符(14.6)后跟带括号的表达式列表 ,在给定表达式列表的情况下构造指定类型的值。 如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)等效(在定义中,如果在含义中定义)。
相应的强制转换表达式为:
表达式(T)cast-expression的结果是T类型。如果T是左值引用类型或函数类型的右值引用,则结果是左值;如果T是对象类型的右值引用,则结果是xvalue; 否则结果是一个prvalue 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.