“no viable conversion” with lemon for clang but valid for g++

做~自己de王妃 提交于 2019-12-04 16:25:51

It's a double dispatch related problem

The code in http://lemon.cs.elte.hu/hg/lemon/file/9fd86ec2cb81/lemon/path.h#l443

template <typename CPath>
void buildRev(const CPath& path) {
    int len = path.length();
    data.resize(len);
    int index = len;
    for (typename CPath::RevArcIt it(path); it != INVALID; ++it) {
        --index;
        data[index] = it;; // sic!
    }
}

relies on this user-defined cast-operator of the iterator on the right hand side

http://lemon.cs.elte.hu/hg/lemon/file/9fd86ec2cb81/lemon/bits/path_dump.h#l139

operator const typename Digraph::Arc() const {
    return path->predMatrixMap(path->source, current);
}

but the left hand type of the assigment expression

http://lemon.cs.elte.hu/hg/lemon/file/9fd86ec2cb81/lemon/list_graph.h#l89

class Arc {
    friend class ListDigraphBase;
    friend class ListDigraph;
protected:
    int id;
    explicit Arc(int pid) { id = pid;}
public:
    Arc() {}
    Arc (Invalid) { id = -1; }
    bool operator==(const Arc& arc) const {return id == arc.id;}
    bool operator!=(const Arc& arc) const {return id != arc.id;}
    bool operator<(const Arc& arc) const {return id < arc.id;}
};

doesn't have a custom assignment operator, but a single-argument custom ctor that clang tries to match against conversions of the right side. And fails.

Patching the right side of above shown lemon/path.h, line #443 with an simple explicit cast operator invocation

   data[index] =  it.operator const typename Digraph::Arc();; 

makes the code at least compile with clang (3.5).

The lemon-developers must decide whether this is desired behavior; a bug report should be filed for this.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!