2013-04-10 63 views
2

std :: shared_ptr :: operator *通過左值引用返回,並且在重載指針(如操作here)上給出的答案表示約定是通過左值引用返回的。但是,當我使用以下代碼時,出現錯誤C2664:'AdjacencyList :: addVertex':無法將參數1從'adjacencyList :: vertex_type'轉換爲'AdjacencyList :: vertex_type & &':您無法將左值綁定到右值參考:如何包裝指針與右值引用一起工作?

std::shared_ptr<vertex_type> AdjacencyList::addVertex(vertex_type&& v) 
{ 
    auto existingVertex(findVertex(v)); 

    if (!existingVertex.isValid()) 
    { 
     existingVertex = std::make_shared<vertex_type>(std::forward<vertex_type>(v)) 
     m_vertices.push_back(existingVertex); 
    } 

    return existingVertex; 
}; 

AdjacencyList minimumSpanningTree; 
// startVertex is a shared_ptr to a vertex returned from a previous call of addVertex 
// on another AdjacencyList object 
const auto mstStartVertex(minimumSpanningTree.addVertex(*startVertex)); 

我應該提供鄰接表:: addVertex(常量vertex_type & v)或改變以上述塊的底部的代碼傳遞到addVertex之前,使頂點的副本?

AdjacencyList minimumSpanningTree; 
Vertex s(*startVertex); 
const auto mstStartVertex(minimumSpanningTree.addVertex(std::move(s))); 

回答

1

的冗餘副本來看,最有效的方法是提供右值和常引用過載:

std::shared_ptr<vertex_type> AdjacencyList::addVertex(vertex_type&&); 
std::shared_ptr<vertex_type> AdjacencyList::addVertex(const vertex_type&); 

爲了消除冗餘代碼,你可以轉發給一個模板方法或具體方法採取bool標誌並酌情執行const_cast

如果複製Vertex對象的開銷與代碼增加的代價相比很小,並且通常或經常輸入if塊,那麼冗餘副本將使代碼更清晰。你的第二個建議的通話將更好地工作,如果你只是建立一個臨時prvalue並不需要移動:

const auto mstStartVertex(minimumSpanningTree.addVertex(Vertex{*startVertex})); 

然而,在這種情況下,你不妨創建呼叫本身暫時的,通過提供一個單一的值過載(How to reduce redundant code when adding new c++0x rvalue reference operator overloads):

std::shared_ptr<vertex_type> AdjacencyList::addVertex(vertex_type); 
2

我認爲你應該從你operator*返回副本,作爲std::weak_ptr的語義學對建議大家不能保證返回的引用將保持有效。由於返回的副本然後被賦予可以將其移動到其他地方的功能,因此addVertex看起來像它將需要副本,即,如果創建爲addVertex的超負荷,它應該也是足夠高效的在內部創建傳遞的const引用的副本,會嗎?

+0

它不一定會生成頂點的副本;目前我看看是否已經添加了相同的頂點,如果有,我什麼都不做。在大多數情況下,它會複製。 – masrtis 2013-04-10 05:36:31

+0

更新後,我不確定是否理解'weak_ptr'或包裝器的需要。你爲什麼不只是返回'std :: shared_ptr '? – 2013-04-10 05:40:16

+0

如果AdjacencyList超出範圍或頂點被刪除,但某人正在頂住頂點,我不想保留頂點信息。最好的例子,雖然與我的特定用例無關,但我可以想到的是爲具有動態導航圖的遊戲中的多個幀中運行的多個代理程序安排路徑查找。也許在AdjacencyList中存儲unique_ptr並返回索引會更好? – masrtis 2013-04-10 05:55:17