2014-05-02 79 views
1

我想共享地圖和另一矢量如下面的代碼之間的引用:從另一個 C++地圖,載體,對與參考

int x = 2; 
f(x); 

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)); 
    } 

} 

和調用該函數

但是這不能編譯。

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.人們是否看到任何這方面的利弊VS指針爲基礎的方法?

回答

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的密鑰。 A std::map是一個已排序的容器,您不能只從外部更改密鑰。這會弄亂std::map的內部工作。

1

您不能擁有一個引用的容器。

引用必須在聲明點初始化,並聲明容器的引用意味着稍後再填充該容器。

您可以改用指針。擁有指針的非(內存)被認爲是有效的C++風格。

第二選擇是將look into

std::reference_wrapper 
+0

這是非常可能有一個容器,存儲'對'! – Danvil

+1

@Danvil真的嗎?參考既不可複製也不可移動;這同樣適用於包含參考的一對。所有標準容器都要求包含的物體可以是可複製的或可移動的。 –

+0

@JamesKanze:看到我的答案。 – Danvil

1

由於類型不匹配的:

vector< pair<T&, int> > v1; // value_type is pair<int&, int> 
//  ^^^^^^^^^^^^^ 

v1.push_back(make_pair(kv.first, 0)); 
//   ^^^^^^^^^^^^^^^^^^^^^^  pair<int, int> 

甲左值引用到int不能與右值進行初始化。

0

如果你真的想引用地圖中的同一個對象和你的對的向量,那麼你最好看看基於指針的解決方案。如果你的原始類型是基於堆棧的,那麼你的二級集合可以使用一個原始指針 - 因爲它沒有關鍵對象的所有權,所以不應該在保留或破壞它的任何角色 - 要遵守它。雖然您必須小心處理同步的兩個集合,以避免任何懸掛指針。

這就是說,取決於你爲什麼要這樣做,如果它是一個簡單的int它可能不值得的複雜性。

+0

'shared_ptr'一般不是一個好的解決方案;據推測,如果他想參考,這些對象是在其他地方管理的 - 最有可能是靜態或自動生命期。原始指針是這裏最好的解決方案。 –

+0

@JamesKanze:是的,如果是這樣的話,你是對的 - 生指針會是更好的解決方案。我會更新答案澄清。 –