2016-09-18 6 views
0

Я пытаюсь получить доступ к edge_ внутри моего Node Struct, поэтому я могу сделать for-loop, чтобы скопировать ребра на новый объект графа для моего конструктора копий.Конструктор глубоких копий для нового графа

Я получаю следующую ошибку, которая меня смущает, когда я пытаюсь получить доступ к краям в узле.

tests/Graph.tem:280:24: error: ‘struct std::pair<const std::__cxx11::basic_string<char>, std::shared_ptr<gdwg::Graph<std::__cxx11::basic_string<char>, int>::Node> >’ has no member named ‘edges_’ 
    for (auto edge: node.edges_) { 
        ~~~~~^~~~~~ 

Я пытаюсь сделать конструктор копирования, который копирует глубокие узлы и ребра внутри графа над новым объектом графа:

template <typename N, typename E> 
Graph<N, E>::Graph(const Graph &g): 
    nodes_{g.nodes_} 
    { 

     for (auto node: g.nodes_) { 

      for (auto edge: node.edges_) { 

      } 

     } 


    } 

Ниже мой график класс:

template <typename N, typename E> class Graph { 

    private: 
     struct Node; 
     struct Edge; 

     struct Node { 
      N val_; 
      int numEdges_; 
      int numIncomingEdges_; 
      std::set<std::shared_ptr<Edge>> edges_; 
      std::set<std::shared_ptr<Edge>> incomingEdges_; 
      Node() {} 
      Node(const N x) : val_{x} { numEdges_=0; numIncomingEdges_=0; } 
      void printNode(N n); 
      ~Node(); 
      void update(); 
     }; 

     struct Edge { 
      std::weak_ptr<Node> orig; 
      std::weak_ptr<Node> dest; 
      E val_; 
      Edge(std::shared_ptr<Node> o, std::shared_ptr<Node> d, E x); 
      Edge() {}; 
      void printEdge(); 
      ~Edge(); 
     }; 

Во-первых, как мне получить к нему доступ к глубокой копии? Кажется, есть проблема с ptr. Во-вторых, есть ли простой способ глубоко скопировать края, хранящиеся внутри узла?

+0

Каков тип 'Graph :: nodes_'? Если это 'std :: map >', как указывает ваше сообщение об ошибке, 'node' имеет тип' std :: pair > ', поэтому вместо' node.edges_' вы должны использовать 'node.second-> edge_'. – Franck

+0

std :: map > nodes_; – iteong

+0

поэтому для первой проблемы вы должны заменить 'for (auto edge: node.edges_)' by 'for (auto edge: node.second-> edge_)'. – Franck

ответ

1

Для сообщения компилятора, вы должны заменить for (auto edge: node.edges_) на for (auto edge: node.second->edges_)

Чтобы выполнить глубокую копию, вам нужна ассоциативная карта между исходными узлами g и узлами вашей копии.

Вот идея кода, который я бы написал для вашего конструктора глубоких копий (я не пытался его скомпилировать).

template <typename N, typename E> 
Graph<N, E>::Graph(const Graph &g): 
    nodes_{g.nodes_} 
    { std::map<Node*, Node*> associativeMap; 
     typename std::map<N, std::shared_ptr<Node>>::const_iterator 
      thisIter(nodes_.begin()), sourceIter(g.nodes_.begin()), 
      thisIterEnd(nodes_.end()), sourceIterEnd(g.nodes_.end()); 
     for (; thisIter != thisIterEnd; ++thisIter) { 
      associativeMap.insert(std::make_pair(&*(sourceIter->second), &*(thisIter->second)); 
      ++sourceIter; 
     } 

     thisIter = nodes_.begin(); 
     for (auto sourceNode: g.nodes_) { 
      Node* thisNode = &*thisIter->second; 
      for (auto sourceEdge: sourceNode.second->edges_) 
       addEdge(*thisNode, *associativeMap[&*sourceEdge->dest], ...); 
      ++thisIter; 
     } 
    } 

Он основан на методе addEge с подписью void addEdge(Node& origin, Node& destination, ...).

Если ваш график :: nodes_ скоро отсортирован и если addEdge может извлечь узлы из ключа - если его подпись bool addEdge(const N& orig, const N& dest, const E& val) -, то associativeMap не более полезен. В этом случае код намного проще.

template <typename N, typename E> 
Graph<N, E>::Graph(const Graph &g): nodes_{g.nodes_} 
{ for (auto sourceNode: g.nodes_) { 
     for (auto sourceEdge: sourceNode.second->edges_) 
     addEdge(sourceNode.second->val_, sourceEdge->dest.lock()->val_, sourceEdge->val_); 
    } 
}