error: call of overloaded distance is ambiguous
error: call of overloaded distance is ambiguous
我有一些代码(我没有写,但正在尝试编译)-- iostream_combo.cc--,这样做会给我以下错误:
./moses/moses/comboreduct/combo/iostream_combo.cc: In function ‘std::__cxx11::string opencog::combo::l2ph(const string&, const std::vector<std::__cxx11::basic_string<char> >&)’:
./moses/moses/comboreduct/combo/iostream_combo.cc:543:64: error: call of overloaded ‘distance(std::vector<std::__cxx11::basic_string<char> >::const_iterator, __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >&)’ is ambiguous
arity_t idx = distance(labels.begin(), found_it) + 1;
^ In file included from /usr/include/c++/8/bits/stl_algobase.h:66,
from /usr/include/c++/8/bits/char_traits.h:39,
from /usr/include/c++/8/ios:40,
from /usr/include/c++/8/ostream:38,
from /usr/include/c++/8/iostream:39,
from ./moses/moses/comboreduct/combo/iostream_combo.h:28,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/include/c++/8/bits/stl_iterator_base_funcs.h:138:5: note: candidate: ‘typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename std::iterator_traits<_Iterator>::difference_type = long int]’
distance(_InputIterator __first, _InputIterator __last)
^~~~~~~~ In file included from /usr/local/include/boost/range/distance.hpp:18,
from /usr/local/include/boost/range/functions.hpp:21,
from /usr/local/include/boost/range/iterator_range_core.hpp:38,
from /usr/local/include/boost/lexical_cast.hpp:30,
from ./moses/moses/comboreduct/combo/iostream_combo.h:30,
from ./moses/moses/comboreduct/combo/iostream_combo.cc:24:
/usr/local/include/boost/iterator/distance.hpp:49:9: note: candidate: ‘constexpr typename boost::iterators::iterator_difference<Iterator>::type boost::iterators::distance_adl_barrier::distance(SinglePassIterator, SinglePassIterator) [with SinglePassIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename boost::iterators::iterator_difference<Iterator>::type = long int]’
distance(SinglePassIterator first, SinglePassIterator last)
^~~~~~~~
我正在使用 Ubuntu 16.04 x64、Boost 1.68 和 gcc 8.2。因此,重现问题的步骤如下:
- 在 Ubuntu 16.04
- 安装
gcc-8
- 使用它从源代码构建 boost 1.68
- Git 克隆 moses repository 沙子按照那里的说明进行操作:基本上 1) git 克隆并构建
cogutil
; 2)尝试制作moses
:
cd build
, cmake ..
, make
.
我对 C++ 的理解足够(我认为),所以我可以看到对 std::distance
的调用超载了。我没有看到消除歧义的方法,尽管我猜它必须包括 found_it
的一些重写或一些显式转换而不是 auto
.
电话是这样的:
arity_t idx = distance(labels.begin(), found_it) + 1;
这意味着 distance
是通过 ADL 找到的,因此会考虑所有关联的名称空间。如果例如,这可能会证明是有问题的。有两个命名空间为 distance
:
提供同样适用的重载
#include <iterator>
#include <vector>
namespace OyVeh {
struct X { };
template <typename It>
size_t distance(It, It) { return 42; } // just to throw in a wrench
}
int main() {
std::vector<OyVeh::X> v{3};
auto f = v.begin();
auto l = v.end();
// now f and l have both `::std` and `::OyVeh` as associated namespaces. The following is ambiguous:
return distance(f, l);
}
大致有两种修复方法:
- 从关联的命名空间中删除模棱两可的
distance
声明(如果竞争者是 std::distance
和 boost::distance
,这可能是不可能的)
- 编辑调用以消除对 ADL 的依赖(例如,将它们限定为
std::distance(...)
或将它们括起来 (distance)(...)
)
显示解决方法:
{
using OyVeh::distance;
return (distance)(f, l); // parentheses suppress ADL
}
return std::distance(f, l); // also works, obviously
return OyVeh::distance(f, l); // but beware the meaning might change
我有一些代码(我没有写,但正在尝试编译)-- iostream_combo.cc--,这样做会给我以下错误:
./moses/moses/comboreduct/combo/iostream_combo.cc: In function ‘std::__cxx11::string opencog::combo::l2ph(const string&, const std::vector<std::__cxx11::basic_string<char> >&)’: ./moses/moses/comboreduct/combo/iostream_combo.cc:543:64: error: call of overloaded ‘distance(std::vector<std::__cxx11::basic_string<char> >::const_iterator, __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >&)’ is ambiguous arity_t idx = distance(labels.begin(), found_it) + 1; ^ In file included from /usr/include/c++/8/bits/stl_algobase.h:66, from /usr/include/c++/8/bits/char_traits.h:39, from /usr/include/c++/8/ios:40, from /usr/include/c++/8/ostream:38, from /usr/include/c++/8/iostream:39, from ./moses/moses/comboreduct/combo/iostream_combo.h:28, from ./moses/moses/comboreduct/combo/iostream_combo.cc:24: /usr/include/c++/8/bits/stl_iterator_base_funcs.h:138:5: note: candidate: ‘typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename std::iterator_traits<_Iterator>::difference_type = long int]’ distance(_InputIterator __first, _InputIterator __last) ^~~~~~~~ In file included from /usr/local/include/boost/range/distance.hpp:18, from /usr/local/include/boost/range/functions.hpp:21, from /usr/local/include/boost/range/iterator_range_core.hpp:38, from /usr/local/include/boost/lexical_cast.hpp:30, from ./moses/moses/comboreduct/combo/iostream_combo.h:30, from ./moses/moses/comboreduct/combo/iostream_combo.cc:24: /usr/local/include/boost/iterator/distance.hpp:49:9: note: candidate: ‘constexpr typename boost::iterators::iterator_difference<Iterator>::type boost::iterators::distance_adl_barrier::distance(SinglePassIterator, SinglePassIterator) [with SinglePassIterator = __gnu_cxx::__normal_iterator<const std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; typename boost::iterators::iterator_difference<Iterator>::type = long int]’ distance(SinglePassIterator first, SinglePassIterator last) ^~~~~~~~
我正在使用 Ubuntu 16.04 x64、Boost 1.68 和 gcc 8.2。因此,重现问题的步骤如下:
- 在 Ubuntu 16.04
- 安装
gcc-8
- 使用它从源代码构建 boost 1.68
- Git 克隆 moses repository 沙子按照那里的说明进行操作:基本上 1) git 克隆并构建
cogutil
; 2)尝试制作moses
:cd build
,cmake ..
,make
.
我对 C++ 的理解足够(我认为),所以我可以看到对 std::distance
的调用超载了。我没有看到消除歧义的方法,尽管我猜它必须包括 found_it
的一些重写或一些显式转换而不是 auto
.
电话是这样的:
arity_t idx = distance(labels.begin(), found_it) + 1;
这意味着 distance
是通过 ADL 找到的,因此会考虑所有关联的名称空间。如果例如,这可能会证明是有问题的。有两个命名空间为 distance
:
#include <iterator>
#include <vector>
namespace OyVeh {
struct X { };
template <typename It>
size_t distance(It, It) { return 42; } // just to throw in a wrench
}
int main() {
std::vector<OyVeh::X> v{3};
auto f = v.begin();
auto l = v.end();
// now f and l have both `::std` and `::OyVeh` as associated namespaces. The following is ambiguous:
return distance(f, l);
}
大致有两种修复方法:
- 从关联的命名空间中删除模棱两可的
distance
声明(如果竞争者是std::distance
和boost::distance
,这可能是不可能的) - 编辑调用以消除对 ADL 的依赖(例如,将它们限定为
std::distance(...)
或将它们括起来(distance)(...)
)
显示解决方法:
{
using OyVeh::distance;
return (distance)(f, l); // parentheses suppress ADL
}
return std::distance(f, l); // also works, obviously
return OyVeh::distance(f, l); // but beware the meaning might change