"no viable conversion" 用柠檬表示 clang 但对 g++ 有效
"no viable conversion" with lemon for clang but valid for g++
目前,我正在尝试将柠檬库合并到我们的项目中。
大多数开发人员都在 Windows,他们用 MSVC 编译,但我负责(这部分)用 gcc 和 clang 编译。
我遇到了 gcc 无法重现的 clang 错误,我设法减少了代码:
#include <lemon/dfs.h>
int main() {
lemon::ListDigraph g{};
lemon::ListDigraph::Node node = g.nodeFromId(42);
lemon::Dfs<lemon::ListDigraph> dfs{g};
lemon::SimplePath<lemon::ListDigraph> path = dfs.path(node);
return 0;
}
使用 gcc,没有错误。
/usr/bin/g++-5 -std=c++11 -Wall -O3 -I${SRC_ROOT}/external/lemon/latest -I${BIN_ROOT}/lemon -o ${TMP_ROOT}/core/src/core.cpp.o -c ${SRC_ROOT}/core/src/core.cpp
但是有 clang:
/usr/bin/clang++-3.7 -std=c++11 -Wall -stdlib=libc++ -O3 -I${SRC_ROOT}/external/lemon/latest -I${BIN_ROOT}/lemon -o ${TMP_ROOT}/core/src/core.cpp.o -c ${SRC_ROOT}/core/src/core.cpp
In file included from ${SRC_ROOT}/core/src/core.cpp:1:
In file included from ${SRC_ROOT}/external/lemon/latest/lemon/dfs.h:31:
${SRC_ROOT}/external/lemon/latest/lemon/path.h:408:23: error: no viable
conversion from 'typename PredMapPath<ListDigraph, NodeMap<Arc> >::RevArcIt' to
'lemon::ListDigraphBase::Arc'
data[index] = it;;
^~
备注:
SRC_ROOT
、BIN_ROOT
、TMP_ROOT
被替换以提高可读性
- 片段源代码无法运行,但应该可以编译(我会更正真正的大代码)
- 我真的需要真正源代码的 c++11 特性。
gcc
5
clang
3.7
lemon
1.3.1
问题:
- 我是不是忘了打旗子了?
- 柠檬是否与 clang 完全兼容?
- 如何解决这个错误?
这是一个 double dispatch 相关的问题
代码在
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!
}
}
依赖于这个用户定义的cast-operator右边的迭代器
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);
}
但是赋值表达式的左手类型
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;}
};
没有自定义赋值运算符,但有一个 clang 尝试匹配右侧转换的单参数自定义构造函数。失败了。
修补上面显示的右侧lemon/path.h, line #443
使用简单的显式转换运算符调用
data[index] = it.operator const typename Digraph::Arc();;
使代码至少可以用 clang (3.5) 编译。
柠檬开发者必须决定这是否是期望的行为;应该为此提交错误报告。
目前,我正在尝试将柠檬库合并到我们的项目中。 大多数开发人员都在 Windows,他们用 MSVC 编译,但我负责(这部分)用 gcc 和 clang 编译。
我遇到了 gcc 无法重现的 clang 错误,我设法减少了代码:
#include <lemon/dfs.h>
int main() {
lemon::ListDigraph g{};
lemon::ListDigraph::Node node = g.nodeFromId(42);
lemon::Dfs<lemon::ListDigraph> dfs{g};
lemon::SimplePath<lemon::ListDigraph> path = dfs.path(node);
return 0;
}
使用 gcc,没有错误。
/usr/bin/g++-5 -std=c++11 -Wall -O3 -I${SRC_ROOT}/external/lemon/latest -I${BIN_ROOT}/lemon -o ${TMP_ROOT}/core/src/core.cpp.o -c ${SRC_ROOT}/core/src/core.cpp
但是有 clang:
/usr/bin/clang++-3.7 -std=c++11 -Wall -stdlib=libc++ -O3 -I${SRC_ROOT}/external/lemon/latest -I${BIN_ROOT}/lemon -o ${TMP_ROOT}/core/src/core.cpp.o -c ${SRC_ROOT}/core/src/core.cpp
In file included from ${SRC_ROOT}/core/src/core.cpp:1:
In file included from ${SRC_ROOT}/external/lemon/latest/lemon/dfs.h:31:
${SRC_ROOT}/external/lemon/latest/lemon/path.h:408:23: error: no viable
conversion from 'typename PredMapPath<ListDigraph, NodeMap<Arc> >::RevArcIt' to
'lemon::ListDigraphBase::Arc'
data[index] = it;;
^~
备注:
SRC_ROOT
、BIN_ROOT
、TMP_ROOT
被替换以提高可读性- 片段源代码无法运行,但应该可以编译(我会更正真正的大代码)
- 我真的需要真正源代码的 c++11 特性。
gcc
5clang
3.7lemon
1.3.1
问题:
- 我是不是忘了打旗子了?
- 柠檬是否与 clang 完全兼容?
- 如何解决这个错误?
这是一个 double dispatch 相关的问题
代码在 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!
}
}
依赖于这个用户定义的cast-operator右边的迭代器
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);
}
但是赋值表达式的左手类型
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;}
};
没有自定义赋值运算符,但有一个 clang 尝试匹配右侧转换的单参数自定义构造函数。失败了。
修补上面显示的右侧lemon/path.h, line #443
使用简单的显式转换运算符调用
data[index] = it.operator const typename Digraph::Arc();;
使代码至少可以用 clang (3.5) 编译。
柠檬开发者必须决定这是否是期望的行为;应该为此提交错误报告。