Меня смущает поведение следующего кода: я не понимаю, почему метод getNodeSuccess
работает, но метод getNodeFail
не удается построить. Единственное различие между этими двумя методами состоит в том, что один использует оператор []
для доступа к карте, а другой - метод at
. Я думал, что обе эти операции возвращают ссылку на элемент на карте, и обе должны в основном делать то же самое. Однако, когда я использую оператор []
вместо метода at()
, он пытается вызвать конструктор по умолчанию класса GraphNode. Поскольку конструктор по умолчанию является закрытым, сборка завершается неудачей.
Для демонстрации я сделал конструктор по умолчанию класса GraphNode
закрытым. Если я изменю его на publi c, то это сработает.
Может кто-нибудь объяснить, что здесь происходит? Почему один метод вызывает конструктор по умолчанию, а не другой?
#include <vector>
#include <list>
#include <unordered_map>
#include <exception>
template <class T>
struct GraphNode
{
int id;
T data;
std::list<int> adj; // adjacency list
GraphNode(const int id)
{
this->id = id;
}
private:
GraphNode() {}
};
template<class T>
struct UndirectedGraph
{
std::unordered_map<int, GraphNode<T>> lookup;
std::vector<GraphNode<T>> vertices;
void addNode(const GraphNode<T> node)
{
// if the id of the node already exists, than we cannot add it
if (lookup.find(node.id) == lookup.end())
lookup.insert(std::make_pair(node.id, node));
else
throw std::runtime_error("Trying to add a node that already exists.");
}
void addEdge(const int source, const int destination)
{
getNodeSuccess(source).adj.push_back(destination);
getNodeSuccess(destination).adj.push_back(source);
getNodeFail(source).adj.push_back(destination);
getNodeFail(destination).adj.push_back(source);
}
GraphNode<T>& getNodeSuccess(const int id)
{
if (lookup.find(id) == lookup.end())
throw std::runtime_error("Trying to retrieve a node that doesn't exist");
return lookup.at(id);
}
GraphNode<T>& getNodeFail(const int id)
{
if (lookup.find(id) == lookup.end())
throw std::runtime_error("Trying to retrieve a node that doesn't exist");
return lookup[id];
}
};
int main(int argc, char* argv[])
{
UndirectedGraph<int> graph;
graph.addNode(GraphNode<int>(1));
graph.addNode(GraphNode<int>(3));
graph.addEdge(1, 3);
return 0;
}