2013-12-17 94 views
0

我試圖爲學習目的實現各種數據結構和算法。unordered_map的問題

目前我正試圖實現一個Graph類模板,但我在嘗試使用STL unordered_map(和將來的consequently priority_queue)時遇到了問題。

基本上,目前發生的情況是,由於某種原因,模板類型在嘗試初始化圖形內的頂點映射時不匹配。據我所知,因爲我只打算使用本地C++類型的鍵類型,只要我的值類型是一個指針,除了我自定義頂點類的拷貝構造函數外,我不需要做任何額外的工作。默認比較器/散列器應該就足夠了。但它並沒有,我收到的錯誤有點不可理解。

錯誤:

Error 1 error C2679: binary '=' : no operator found which takes a right-hand operand of type 'std::unordered_map<T,graph<T>::vertex *,std::hash<int>,std::equal_to<_Kty>,std::allocator<std::pair<const _Kty,_Ty>>>' (or there is no acceptable conversion) 

代碼:

#include "stdafx.h" 
#include <iostream> 
#include <vector> 
#include <unordered_map> 
#include <numeric> 
#include <functional> 

using namespace std; 
class vertex; 
template <class T> 
class graph { 
public: 

graph() { verts = unordered_map<T, vertex*>(); } 
~graph() { 
    for each(auto v in verts) 
     delete(v); 
    delete(verts); 
} 
private: 
unordered_map<T, vertex*> verts; 

// --- Inner Classes --- 

struct path { 
    vertex *dest; 
    double cost; 

    path(vertex *d = nullptr, double c = 0.0) : dest(d) : cost(c) {} 

    inline int compare(const path& p) { 
     auto other = p.cost; 

     return cost < other ? -1 : 
      cost > other ? 1 : 0; 
    } 
}; 

struct edge { 
    vertex *dest; 
    double cost; 

    edge(vertex *d = nullptr, double c = 0.0) : dest(d) : cost(c) {} 
}; 

class vertex { 
public: 
    // Vertex relationships 
    T name; 
    vector<edge>* adj; 

    // Path Finding Information 
    double distance; 
    vertex *prev; 
    int scratch; 

    void reset_path_finding() { 
     distance = double.infinity(); 
     prev = nullptr; 
     scratch = 0; 
    } 

    vertex(T name = default(T)) : name(name) : adj(new vector<edge>) : 
     distance(double.infinity()) : prev(nullptr) : scratch(0) {} 
    vertex(const vertex& v) { 
     name = v.name; 
     adj = v.adj; 
     distance = v.distance; 
     prev = v.prev; 
     scratch = v.scratch; 
    } 
    ~vertex() { delete(adj); } 
private: 
}; 
}; 

int main() 
{ 
graph<int> myGraph = graph<int>(); 

cout << "Press any key to continue..." << endl; 
int x; 
cin >> x; 
return 0; 
} 
+0

你能指出錯誤是關於源的行嗎? –

+1

順便說一句,當你聲明一個變量(類成員,本地或全局),如'main'函數中的本地'myGraph'或'graph'類中的'verts'時,你不必初始化你做。只要宣佈它就足夠了。 –

回答

3

第一個問題是,你宣佈之前使用嵌套類graph::vertex。進一步的混淆是因爲你宣稱class vertex以外 ,所以編譯器最初認爲你的意思是這個類。你可以聲明vertex的附近開始:

template <class T> 
class graph { 
    class vertex; 
private: 
    // and so on 
}; 

還有其他一些語法錯誤,如果你看一下在錯誤消息中提到的線,應該是顯而易見的。對於語法的範圍爲基礎的循環是

for (auto v : verts) // not for each(auto v in verts) 

這給你鍵值對,所以刪除vertex,你需要

delete v.second; 

更妙的是,改變vertsunordered_map<T, vertex>,包含對象而不是指針,它會自動管理所有的內存 - 你根本不需要析構函數。

path(vertex *d = nullptr, double c = 0.0) : dest(d) , cost(c) {} 
                ^not : 

一個double與無限價值爲

在構造函數的初始化器列表中的值初始化的暫時是

T() // not default(T) 

從句的語法用逗號,沒有冒號隔開

std::numeric_limits<double>::infinity() // not double.infinity() 

您需要包含<limits>

verts不需要在析構函數中刪除,因爲你不需要new它。它也不需要在構造函數中從默認構造的臨時對象中分配,因爲它只是默認構造的。

有幾個地方,你通過不必要的指針和new使自己生活困難。儘量避免new,除非你真的需要它;並瞭解有關RAII,特別是智能指針和容器的使用,當您這樣做時。

+0

哇,謝謝。我打算取消這段代碼,明天再做這個反饋。我試圖讓它工作起來,我已經夠了。 但是,當我嘗試編譯整個類時,你指出的很多內容甚至不會出現錯誤消息。 (MS C++)除非我強制它作爲一個小測試片段,有時甚至不是那樣。例如,對於每個語法都不正確的編譯和行爲如預期。 我在這臺新電腦上下載了鐺聲,但由於我住在農村地區,下載需要一段時間。 – BlamKiwi

+0

@MorphingDragon:因爲它是一個模板,所以很多錯誤都不會被檢測到,除非它們所在的函數或類被實例化 - 除非程序使用它,否則不會(通常)發生。嘗試通過一次添加一小部分功能來構建大型課程,隨時編寫測試,這樣您就不會有大量錯誤需要拖拽。 –