错误:重载距离的调用不明确 [英] error: call of overloaded distance is ambiguous

查看:143
本文介绍了错误:重载距离的调用不明确的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些代码(我没有写,但是正在尝试编译)-

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:

  1. 在Ubuntu 16.04上
  2. 安装gcc-8
  3. 使用它从源代码构建升压1.68
  4. Git克隆 moses仓库遵循那里的说明:基本上1)git clone并构建cogutil; 2)尝试使moses: cd buildcmake ..make.
  1. On Ubuntu 16.04
  2. install gcc-8
  3. Use it to build boost 1.68 from source
  4. Git clone the moses repository sand follow the instructions from there: basically 1) git clone and build cogutil; 2) try to make moses: 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:

在Coliru上直播

#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::distanceboost::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 are std::distance and boost::distance)
  • edit the calls to remove the reliance on ADL (e.g. qualify them like std::distance(...) or parenthesize them (distance)(...))

显示解决方法:

在Coliru上直播

{
    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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆