从匹配返回值类型的映射返回值

时间:2016-05-14 19:08:27

标签: c++ constructor compiler-errors

我收到以下错误

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是完整编译器输出的要点。

3 个答案:

答案 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_typeVertex)为默认可构造 1 ,因为它会插入默认构造的 1 mapped_type如果地图中没有关键字。这是一个运行时决策,因此即使密钥实际存在,您仍然需要在编译时使用默认构造函数。

在C ++ 17中,使用try_emplace

Vertex getmake_vertex(const int v) {
    return vertices.try_emplace(v, v).first->second;
}

否则,请使用insertemplace

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