我可以通过复制构造函数从非原始类型变量复制,并通过右值引用函数参数传递它。
但是如何使用原始类型变量做到这一点呢?
例如:
#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 扩展允许右值绑定(bind)到左值引用的错误(因为右值引用无论如何都是更好的匹配)。
您可以使用 /Za
开关来解决这个问题。
表达式 int(x2)
被 C++14 [expr.type.conv]/2 覆盖(C++11 具有相同的编号):
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).
对应的cast表达式为:
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.
关于c++ - 传递右值引用函数参数时如何从原始类型变量复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26480413/