c++ - 传递右值引用函数参数时如何从原始类型变量复制

标签 c++ visual-studio-2013 rvalue-reference primitive-types lvalue

我可以通过复制构造函数从非原始类型变量复制,并通过右值引用函数参数传递它。

但是如何使用原始类型变量做到这一点呢?

例如:

#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

最佳答案

您的代码是正确的,这似乎是 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 online tester

请注意,进一步的测试表明该错误实际上是 (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/

相关文章:

c++ - wprintf 不打印特殊字符

c++ - Visual C++ 2013 可以做 Purify 和 Quantify 所做的事情吗?

visual-studio-2013 - TFS 2015 工作区删除后不断返回

c++11 emplace_back 和 push_back 语法与结构

c++ - 以不同方式分派(dispatch)右值和左值并使用 sfinae 禁用一个选项

c++ - 将 typeid 的结果分配给变量

c++ - 如何配置 CMake 以特定顺序构建多个项目?

c++ - 数组折叠成单个元素

c++ - 未定义对 Main::playerX 的引用

c++ - 如何获得对右值的引用?