c++ - 带引用的 std::pair 和引用包装器有什么区别
问题描述
我已经陷入了我所做的错误假设。我发现
std::pair<int &, int &>
是一件事。但是我没想到以下会失败
int a = 10;
int b = 20;
int c = 30;
using PRef = std::pair<int &, int &>;
PRef p0 = {a,b};
PRef p1 = {b,c};
EXPECT_EQ(a, 10);
EXPECT_EQ(b, 20);
EXPECT_EQ(c, 30);
p0 = p1;
EXPECT_EQ(a, 10);
EXPECT_EQ(b, 20);
EXPECT_EQ(c, 30);
然而,分配后的第二组测试失败,因为
a is 20 # copied from b
b is 30 # copied from c
我有点期望它的行为类似于引用包装器,其中底层指针将被复制,但这似乎不是它的工作方式。是否有一些明确的理由说明为什么行为与使用不同
std::pair<std::reference_wrapper<int>, std::reference_wrapper<int>>
如果我运行与上面相同的测试但使用 reference_wrapper 则它可以工作。
{
int a = 10;
int b = 20;
int c = 30;
using PRef = std::pair<std::reference_wrapper<int> , std::reference_wrapper<int>>;
PRef p0 = {std::ref(a),std::ref(b)};
PRef p1 = {std::ref(b),std::ref(c)};
EXPECT_EQ(a, 10);
EXPECT_EQ(b, 20);
EXPECT_EQ(c, 30);
p0 = p1;
EXPECT_EQ(a, 10);
EXPECT_EQ(b, 20);
EXPECT_EQ(c, 30);
}
这两种形式之间应该有区别吗?
解决方案
它具有这种行为的原因与
int a = 10;
int b = 20;
int &aref = a;
int &bref = b;
aref = bref;
分配a
给b
。真实引用(相对于引用包装器)不能被反弹。分配给引用会调用它所引用的赋值运算符。
std::reference_wrapper::operator=重新绑定引用。因此,如果aref
和bref
是std::reference_wrapper
s,则分配不会改变a
。
推荐阅读
- java - 如何连接到数据库 psql?
- python - 如何让 python webscraping 更好地更新
- file - 文件权限不正确
- javascript - 使用 js-ipfs 在浏览器中发布的 IPNS 名称不会在网关或本地节点上解析
- javascript - 如何在reactjs中使用downshift设置输入值
- azure - Azure.Search.Documents - 使用集合更新或插入对象
- postgresql - 如何在 PostgreSQL 中存储 unsigned long?
- kotlin - 具有默认函数参数值的 Kotlin 接口
- javascript - Mongoose.js CastError:在模型“Projekt”的路径“访问”处,值“{'$gte':1}”转换为数字失败
- vba - 以特定样式运行高亮宏