I've fallen over a bad assumption that I made. I discovered that
std::pair<int &, int &>
is a thing. However I didn't expect the following to fail
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);
However the second set of tests after the assignment fails because
a is 20 # copied from b
b is 30 # copied from c
I kind of expected this to behave like reference wrapper where the underlying pointer would get copied but this is not how it seems to work. Is there some clear reasoning why the behaviour is different to using
std::pair<std::reference_wrapper<int>, std::reference_wrapper<int>>
If I run the same test as above but with reference_wrapper then it works.
{
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);
}
Is there supposed to be a difference between the two forms?
It has this behavior for the same reason that
Assigns
a
tob
. Real references (as opposed to reference wrappers) can't be rebound. Assigning to a reference calls the assignment operator on what it's referencing.std::reference_wrapper::operator= rebinds the reference. So if
aref
andbref
werestd::reference_wrapper
s the assignment wouldn't changea
.