C ++地图,向量,带引用的对

时间:2014-05-02 07:12:47

标签: c++ reference containers

我正在尝试在地图和另一个向量之间共享引用,如下面的代码所示:

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.人们是否认为这与基于指针的方法有任何缺点?

4 个答案:

答案 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

的内部运作