绑定const std :: pair< T,U&到std :: pair< const T,U>的值 [英] Bind const std::pair<T, U>& to value of std::pair<const T, U>
问题描述
下面的代码段带有一个非常重要的警告。
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;
}
std :: pair<有一个隐式转换; const int,float>
到 std :: pair< int,float>
在 foo(map.begin() )
创建一个悬空的引用。
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;
^~
我们可以调整 r2的类型
到 std :: pair< const int,float>
。不过,在一般情况下,将两次调用的结果分配给类型兼容的引用 foo()
会很有用。例如,对 foo()
的调用可能被包装在另一个始终返回 std :: pair< int,float>&
。
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>&
.
可以对引用赋值进行操作以解决const修饰符未对齐的问题吗?
Can the reference assignment be made to operatate in a way that works around the misalignment of const modifiers?
推荐答案
编辑
问题实际上是关于制作 std :: pair< K,V>
与 std :: pair< const K,V>
一起使用; vector<>
和 map<
是红鲱鱼。 (特别是,请参见此处关于为什么 std :: map<>
中的 key 为什么是 const
。)
The question is really about making std::pair<K,V>
work with std::pair<const K,V>
; vector<>
and map<>
are red-herrings. (In particular, see the discussion here about why the key in std::map<>
is const
.)
更好的示例代码可能是:
Better sample code might be:
#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,...>
。
According to your comments, what you're really trying to figure out is how to make the std::map<>
iterator work like std::vector<>
; the result should be a std::pair<>
in both cases, not std::pair<const int, ...>
.
用这个,我写了这个hack;我确定它有问题和/或可以改进:
With that, I've written this hack; I'm sure it's got problems and/or could be improved:
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);
}
这篇关于绑定const std :: pair< T,U&到std :: pair< const T,U>的值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!