下面的代码片段编译时带有一个非常重要的警告。
#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;
}
存在从std::pair<const int, float>
的隐式转换至 std::pair<int, float>
在foo(map.begin())
期间这会创建一个悬空引用。
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;
^~
我们可以调整 r2
的类型至 std::pair<const int, float>
在这种情况下。尽管如此,在一般情况下,将两次调用的结果分配给 foo()
还是很有用的。类型兼容的引用。例如,调用 foo()
可能包含在另一个始终返回 std::pair<int, float>&
的函数中.
引用赋值能否以一种解决 const 修饰符未对齐的方式进行操作?
最佳答案
编辑
问题实际上是关于制作 std::pair<K,V>
与 std::pair<const K,V>
一起工作; vector<>
和 map<>
是红鲱鱼。 (特别是,请参阅讨论 here 关于为什么 std::map<>
中的 key 是 const
。)
更好的示例代码可能是:
#include <vector>
template <typename iterator>
const std::pair<const int, float>& bar(iterator it)
{
return *it;
}
int main()
{
const std::vector<std::pair<const int, float>> v1{ std::make_pair(0, 0.0f) };
bar(v1.begin());
const std::vector<std::pair<int, float>> v2{ std::make_pair(0, 0.0f) };
bar(v2.begin());
return 0;
}
根据您的评论,您真正想弄清楚的是如何制作 std::map<>
迭代器的工作方式类似于 std::vector<>
;结果应该是 std::pair<>
在这两种情况下,都不是 std::pair<const int, ...>
.
有了这个,我就写了这个 hack;我确定它有问题和/或可以改进:
const auto& remove_const(const std::pair<const int, float>& p) {
return reinterpret_cast<const std::pair<int, float>&>(p); // :-(
}
template <typename iterator>
const std::pair<int, float> &foo(iterator it) {
return remove_const(*it);
}
关于c++ - 将 const std::pair<T, U>& 绑定(bind)到 std::pair<const T, U> 的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41752812/