如何在传递右值引用函数参数时从基元类型变量复制
How to copy from primitive type variables when passing through rvalue reference function arguments
我可以通过复制构造函数从非基元类型变量进行复制,并通过右值引用函数参数传递它。
但是如何使用基元类型变量来实现这一点呢?
例如:
#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在线测试仪
请注意,进一步的测试表明,错误实际上是(int)x2
被MSVC视为左值;MSVC的扩展允许右值绑定到左值引用并不是一个错误(因为右值引用无论如何都是更好的匹配)。
您可以使用/Za
开关来解决此问题。
表达式int(x2)
由C++14[expr.type.conv]/2覆盖(C++11具有相同的编号):
简单类型说明符(7.1.6.2)或类型名说明符(14.6)后接带括号的表达式列表构造给定表达式列表的指定类型的值。如果表达式列表是单个表达式,则类型转换表达式与相应的强制转换表达式(5.4)等效(在定义上,如果在含义上定义)
对应的强制转换表达式为:
表达式(T)强制转换表达式的结果为T类型。如果T是左值引用类型或对函数类型的右值引用,则结果为左值;如果T是对对象类型的右价引用,则为xvalue否则,结果是一个pr值。
相关文章:
- 当从函数参数中的临时值调用复制构造函数时
- 如果有一个模板构造函数只有一个泛型参数,为什么我必须有一个复制构造函数
- 为什么默认复制函数在按值发送参数时不调用?
- std::p ackaged_task 应该删除带有 const 参数的复制 c'tor
- 将参数传递给泛型 lambda 时复制构造函数不正确
- 如何确定捕获不可复制参数的 lambda 的类型?
- 复制 avcodec 参数
- 从函数参数 [C++] 复制整数数组
- 候选构造函数(隐式复制构造函数)不可行:第一个参数需要 l 值
- 使用另一个类中的参数复制构造函数
- 在 c++ 中从参数复制本地数组比从数组更快?
- 是否可以避免将参数复制到 lambda 函数?
- 可以使用默认参数复制包含 lambda 的 std::函数吗?
- C 指针节点帮助 - 将参数复制到链接的列表节点更改该节点的不同部分
- gcc 的 std::bind 在源中的哪个位置将参数复制到数据结构中?
- std::绑定参数复制行为
- 使用参数复制构造函数作为对派生类的引用
- 将指针类参数复制到类成员的好处
- 使用 2 参数复制构造函数
- 函数参数:复制或指针