错误:重载距离的调用不明确 [英] error: call of overloaded distance is ambiguous
问题描述
I have a bit of code (which I didn't write, but am trying to compile) -- iostream_combo.cc--, and doing so gives me the following error:
./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.因此,重现此问题的步骤如下:
I'm using Ubuntu 16.04 x64, Boost 1.68 and gcc 8.2. So, the steps to reproduce the problem would be as follows:
- 在Ubuntu 16.04上
- 安装
gcc-8
- 使用它从源代码构建升压1.68
- Git克隆 moses仓库遵循那里的说明:基本上1)git clone并构建
cogutil
; 2)尝试使moses
:cd build
,cmake ..
,make
.
- On Ubuntu 16.04
- install
gcc-8
- Use it to build boost 1.68 from source
- Git clone the moses repository sand follow the instructions from there: basically 1) git clone and build
cogutil
; 2) try to makemoses
:cd build
,cmake ..
,make
.
我对C ++足够了解(我认为),因此可以看到对std::distance
的调用已超载.我看不到的是消除歧义的方法,尽管我猜想它必须包括对found_it
的一些重写或对auto
的一些显式强制转换.
I understand C++ enough (I think) that I can see that the call to std::distance
is overloaded. What I don't see is the way to disambiguate it, although I guess it must include some re-writing of found_it
or some explicit castings instead of auto
.
推荐答案
调用类似于:
arity_t idx = distance(labels.begin(), found_it) + 1;
这意味着distance
是通过ADL找到的,因此考虑了所有关联的名称空间.如果例如有两个命名空间为distance
提供了同样适用的重载:
This means that distance
is found via ADL and hence all associated namespaces are considered. This might prove problematic if e.g. there are two namespaces providing an equally applicable overload for 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)(...)
)
- remove the ambigious
distance
declaration from the associated namespace (this might not be possible if e.g. the ones competing arestd::distance
andboost::distance
) - edit the calls to remove the reliance on ADL (e.g. qualify them like
std::distance(...)
or parenthesize them(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
这篇关于错误:重载距离的调用不明确的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!