"нет жизнеспособного преобразования" с лимоном для лязга, но действительно для g++
В настоящее время я стараюсь включить лимонную библиотеку в наш проект. Большинство разработчиков работают под Windows, они компилируются с MSVC, но я отвечаю (за эту часть) за компиляцию с gcc и clang.
Я столкнулся с ошибкой clang, что gcc не воспроизводит, и мне удалось уменьшить код:
#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
Но с лязгом
/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
Вопросы:
- Я забыл лягнуть флаг?
- Лимон полностью совместим с лязгом?
- Как решить эту ошибку?
1 ответ
Это проблема двойной доставки
Код в 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!
}
}
опирается на этот пользовательский оператор приведения итератора на правой стороне
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;}
};
не имеет пользовательского оператора присваивания, но пользовательский ctor с одним аргументом, который clang пытается сопоставить с преобразованиями правой стороны. И терпит неудачу.
Патч правая сторона выше показано lemon/path.h, line #443
с простым явным вызовом оператора приведения
data[index] = it.operator const typename Digraph::Arc();;
делает код как минимум компилируемым с помощью clang (3.5).
Разработчики лимонов должны решить, является ли это желаемым поведением; отчет об ошибке должен быть подан для этого.