c++ - std::pair 与引用和引用包装器之间有什么区别

标签 c++ std-pair reference-wrapper

我因自己做出的错误假设而陷入困境。我发现

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=重新绑定(bind)引用。因此,如果 arefbrefstd::reference_wrapper ,则赋值不会更改 a

关于c++ - std::pair 与引用和引用包装器之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63941253/

相关文章:

java - 在 3D 结构中添加新顶点

c++ - 发现跳过小数点后的数字

c++ - 为什么你不能从一个元组中分配一个对,但元组可以从一个对中分配?

c++ - 是否有用于拆分 std::pair 的标准 C++ 函数对象?

c++ - 将引用包装器的 vector 转换为基类,将引用包装器的 vector 转换为派生类,不能动态转换

c++ - std::reference_wrapper 是否应该包含默认比较器 "<"运算符?

c++ - 需要 libstdc++.so.6(GLIBCXX_3.4.21)(64bit)(Centos 7 错误)

c++ - 复制两个不同大小的元组

c++ - 使用 C++ 在 map 中插入 Pair 作为键

c++ - 为什么 reference_wrapper<string> 比较不起作用?