There are cases when I want a reference to an object but instead I get a copy. Here is an example:
std::pair<const std::string, int> foo("hello", 5);
const std::pair<std::string, int> & bar = foo;
std::cout << "foo: " << foo.first << " " << foo.second << std::endl;
std::cout << "bar: " << bar.first << " " << bar.second << std::endl;
foo.second = 7;
std::cout << "foo: " << foo.first << " " << foo.second << std::endl;
std::cout << "bar: " << bar.first << " " << bar.second << std::endl;
This produces:
foo: hello 5
bar: hello 5
foo: hello 7
bar: hello 5
So apparently a copy of foo
has been created while the syntax suggests (to me at least) that the programmer wanted a reference to it.
This violates the principle that a reference should be an alias to something. It would be great if somebody could explain what is going on and why.
(Note: I came across this here)
The underlying types of foo
and bar
are different, so a temporary is created using an implicit conversion from the type on the RHS to the one on the LHS*. The C++ standard allows for a const
reference to bind to a temporary and extend its lifetime.
The const
reference bar
binds to that temporary, which is a distinct object from foo
.
If you were to use the same types, you'd get the result you expect:
std::pair<const std::string, int> foo("hello", 5);
const std::pair<const std::string, int> & bar = foo;
or
std::pair<std::string, int> foo("hello", 5);
const std::pair<std::string, int> & bar = foo;
would yield
foo: hello 5
bar: hello 5
foo: hello 7
bar: hello 7
*std::pair
has a template constructor that allows this implicit conversion from one type of pair to another.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With