我正在尝试在地图和另一个向量之间共享引用,如下面的代码所示:
template <typename T>
void f(T& x) {
std::map<T, vector<int> > mp;
mp[x] = vector<int>(2, 4);
vector< pair<T&, int> > v1;
for (auto& kv : mp) {
v1.push_back( make_pair(kv.first, 0) );
}
}
并从另一个调用此函数
int x = 2;
f(x);
但这不会编译。
error: no matching function for call to ‘std::vector<std::pair<int&, int>, std::allocator<std::pair<int&, int> > >::push_back(std::pair<int, int>)’
v1.push_back( make_pair(kv.first, 0) );
有人知道为什么吗?
修改 我能够使用
std::reference_wrapper
这是我目前的解决方案。
template <typename T>
void f(T& x) {
std::map<std::reference_wrapper<T>, vector<int> > mp;
mp[x] = vector<int>(2, 4);
vector< pair<T&, int> > v1;
for (auto& kv : mp) {
v1.push_back( make_pair( std::ref(kv.first) , 0) );
}
v1[0].first = 34;
}
和
int x = 2;
f(x);
cout << x << endl;
打印34.人们是否认为这与基于指针的方法有任何缺点?
答案 0 :(得分:1)
您不能拥有参考容器。
必须在声明点初始化引用,并且声明引用容器意味着稍后填充该容器。
您可以使用指针代替。非(内存)拥有指针被认为是有效的c ++风格。
第二个选项是look into
std::reference_wrapper
答案 1 :(得分:1)
由于类型不匹配:
vector< pair<T&, int> > v1; // value_type is pair<int&, int>
// ^^^^^^^^^^^^^
和
v1.push_back( make_pair(kv.first, 0) );
// ^^^^^^^^^^^^^^^^^^^^^^ pair<int, int>
无法使用右值初始化对int的左值引用。
答案 2 :(得分:0)
如果你真的想在你的地图中引用相同的对象和对的向量,那么你最好不要看一个基于指针的解决方案。如果您的原始类型是基于堆栈的,那么您的辅助集合可以使用原始指针 - 因为它没有密钥对象的所有权,因此不应该在保留或破坏它时起任何作用 - 遵循它。虽然你必须小心管理两个同步的集合,以避免任何悬空指针。
那就是说,根据你想要这样做的原因,如果它是一个简单的int
,它可能不值得复杂。
答案 3 :(得分:0)
通常,您可以将std::pair<T&,int>
存储在std::vector
中,但必须正确插入值。
make_pair(x, 0)
创建一个没有引用的std::pair<T,int>
。
例如,您可以使用初始化列表:
v.push_back({x,0});
另一种方法是使用std::ref
:
v.push_back(std::make_pair(std::ref(x),0));
示例:强>
std::vector<std::pair<int&,int>> v;
int a = 1;
v.push_back({a,a});
v.push_back(std::make_pair(std::ref(a),a));
a = 2;
std::cout << v[0].first << " " << v[0].second << std::endl; // will write "2 1"
但是为了您的目的,它将无法正常工作。您不应该引用std::map
的密钥。 std::map
是一个已排序的容器,您不能只从外部更改密钥。这会弄乱std::map
。