我收到以下错误
In file included from /Users/james/ClionProjects/United States Computing Olympiad/graphs.cpp:2:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/string:439:
In file included from /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/algorithm:628:
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin/../include/c++/v1/memory:1673:31: error: no matching constructor for initialization of 'Vertex'
::new((void*)__p) _Up(_VSTD::forward<_Args>(__args)...);
以下是我的代码相关部分的删节版本:
class Vertex {
public:
int label;
vector<Vertex> adjacent_vertices;
Vertex(const int l) : label(l) { }
Vertex(const int l, vector<Vertex> adjacents) : label(l), adjacent_vertices(adjacents) { }
Vertex(const Vertex& other_vertex) : label(other_vertex.label), adjacent_vertices(other_vertex.adjacent_vertices){ }
};
class Graph {
public:
unordered_map<int, Vertex> vertices;
protected:
Vertex getmake_vertex(const int v) {
if (vertices.find(v) == vertices.end() ) {
// not found, make new vertex
vertices[v] = Vertex(v);
}
return vertices[v];
};
};
我已经确认,在注释掉所有其他内容的情况下运行它会产生编译器错误。有人可以向我解释为什么会发生这种情况以及如何解决这个问题? Here是完整编译器输出的要点。
答案 0 :(得分:5)
当您说vertices[v] = Vertex(v);
时,必须为密钥Vertex
(在分配之前)创建v
,但Vertex
没有默认构造函数。
您应该使用vertices.insert(make_pair(v, Vertex(v)))
甚至vertices.emplace(v, Vertex(v))
这也适用于return vertices[v];
。即使你和我知道在返回此返回语句时v已经存在v值,但编译器不会且仍然必须生成可能产生一个的代码,这会导致错误。
将其设置为return vertices.find(v)->second;
将修复该部分。无需检查并确保find
值不是end
,因为我们只是将它放入其中。
答案 1 :(得分:1)
使用operator[]
要求您的案例中的mapped_type
(Vertex
)为默认可构造 1 ,因为它会插入默认构造的 1 mapped_type
如果地图中没有关键字。这是一个运行时决策,因此即使密钥实际存在,您仍然需要在编译时使用默认构造函数。
在C ++ 17中,使用try_emplace
:
Vertex getmake_vertex(const int v) {
return vertices.try_emplace(v, v).first->second;
}
Vertex getmake_vertex(const int v) {
return vertices.insert({v, v}).first->second;
}
(如果您制作了Vertex(v)
构造函数Vertex(int)
,则可能需要使用explicit
。
如果密钥已经在地图中,那么实际上不会插入任何内容。所有这三个
返回pair<iterator, bool>
,迭代器指向具有指定键的元素。
1 不完全正确,但对我们的目的来说足够真实。
答案 2 :(得分:0)
如果我读错了这部分错误信息,那么它需要 constructor(private router:Router, private routeSerializer:RouterUrlSerializer, private location:Location) {
router.changes.first().subscribe(() => {
let urlTree = this.routeSerializer.parse(location.path());
console.log('serializer', urlTree.children(urlTree.root)[0].segment);
// or to get the next segment of the path:
// console.log('serializer', urlTree.children(urlTree.children(urlTree.root)[0])[0].segment);
});
}
的默认构造函数;尤其是:
需要2个参数,但提供了0
Vertex