2016-04-22 21 views
2

在這個模板函數中,我試圖從boost ptr_map中檢索元素。爲了清晰起見,我省略了錯誤處理代碼。分配給參考時,爲什麼會出現此錯誤(C2582:'operator ='功能在'B'中不可用)?

template <typename K, class T> 
class A 
{ 
public: 
    void TryGet(const K &key, T &o) { o = mObjects.at(key); } 
private: 
    boost::ptr_map<K, T> mObjects; 
}; 

typedef A<std::string, B> myClass; 

我得到編譯器錯誤C2582:'operator ='函數在'B'中不可用。爲什麼將mObjects.at()的返回值賦值給引用需要訪問實例化類的賦值運算符?什麼是返回這個值的正確方法?

+2

你'TryGet'聲明爲返回一個'bool'但沒有'return' – user463035818

+3

爲什麼分配需要分配?呃... –

+0

它可能與'B'有關,你沒有顯示。 – nobar

回答

3

爲什麼將mObjects.at()的返回值賦值給一個引用需要訪問實例化類的賦值操作符?

當您分配給引用時,您正在爲對象分配參考引用。

int i = 0; 
int& iRef = i; // There is no assignment, just initializing the reference. 
iRef = 10;  // Same as i = 10 

更新,響應OP的評論

你們看到的是等價的:

int j = 10; 
int& jRef = j; 
iRef = jRef;  // Same as i = j 
+0

我看不到這是如何等效的。 mObjects.at(...)返回對象的引用。所以我會認爲行o = mObjects.at(...)更接近你的int&ref = i(即沒有賦值) –

+0

@DrewS。,請參閱更新 –

0

你的代碼的問題是

boost::ptr_map<K, T> mObjects; 

提升:: ptr_map需要帶重載賦值運算符的兩個類。如果你想使用boost,你必須在類型B中重載賦值運算符::: ptr_map

1

現在我明白了。你不知道C++中的引用是如何工作的。也許你對Java的熟悉會讓你偏離正軌。在C++中,引用是簡單的別名 - 所以你試圖直接分配給有問題的對象(你指出這是不合法的)。在Java中,"references"大致相當於C++ smart pointers。通過將不可匹配類型封裝在這些類型中,您可能可以使這種方法奏效。

boost::ptr_map<K, shared_ptr<T> > mObjects; 

void TryGet(const K &key, shared_ptr<T> & o) 
    { 
    o = mObjects.at(key); 
    } 
+0

注意:OP代碼在java中不起作用,因爲對象引用是按值傳遞的(即'o = bla'不會改變調用者的參數) –

+0

@MM:好點。這是關於C++的好事之一 - 記住參數是如何傳遞的很容易,因爲傳遞引用和傳遞指針具有明確的語法。 Java和其他人對參數如何傳遞(和分配)有着微妙的規則。我只是猜測OP在Java中使用術語「reference」的方式不同。 – nobar

2

我認爲你問「爲什麼我不能重新定位參考」?

我的意思是,你創建一個引用(姑且稱之爲ref1)引用變量aint& ref1 = a;),然後如果有另一個參考(ref2)引用變量b(INT & REF2 = B ;`),你想知道爲什麼:

ref1 = ref2; 

不會改變ref1參考b,而不是做a = b

這是正確的嗎? 如果是這樣,答案是「這不是現在引用在C++中工作」。他們只能初始化一次,之後不能更改。

下面是這個話題的討論:Why are references not reseatable in C++

相關問題