The below code snippet compiles with a very important warning.
#include <map>
#include <vector>
template <typename iterator>
const std::pair<int, float> &foo(iterator it) {
return *it;
}
int main() {
std::vector<std::pair<int, float>> vector;
std::map<int, float> map;
vector.push_back(std::make_pair(0, 0.0));
map.insert(std::make_pair(0, 0.0));
const std::pair<int, float> &r1 = foo(vector.begin());
const std::pair<int, float> &r2 = foo(map.begin());
if (r1 != r2) {
return 1;
}
return 0;
}
There is an implicit conversion from std::pair<const int, float>
to std::pair<int, float>
during foo(map.begin())
that creates a dangling reference.
ref2.cpp: In instantiation of ‘const std::pair<int, float>& foo(iterator) [with iterator = std::_Rb_tree_iterator<std::pair<const int, float> >]’:
ref2.cpp:16:52: required from here
ref2.cpp:7:11: warning: returning reference to temporary [-Wreturn-local-addr]
return *it;
^~
We could adjust the type of r2
to std::pair<const int, float>
in this case. Nevertheless, it would be useful, in the general case, to assign the results of the two calls to foo()
to type-compatible references. For example, the call to foo()
might be wrapped in another function that always returns std::pair<int, float>&
.
Can the reference assignment be made to operatate in a way that works around the misalignment of const modifiers?