2013-04-10 43 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