错误:超载距离的调用是模糊的

问题描述 投票:0回答:1

我有一些代码(我没有编写,但我正在尝试编译) - 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。因此,重现问题的步骤如下:

  1. 在Ubuntu 16.04上
  2. 安装gcc-8
  3. 用它从源代码构建boost 1.68
  4. Git克隆moses repository沙子遵循那里的指示:基本上1)git克隆和构建cogutil; 2)尝试制作mosescd buildcmake ..make

我完全理解C ++(我认为)我可以看到对std::distance的调用过载了。我没有看到的是消除歧义的方法,虽然我想它必须包括一些重写found_it或一些明确的铸件而不是auto

c++ c++11 boost std ambiguous
1个回答
1
投票

电话如下:

    arity_t idx = distance(labels.begin(), found_it) + 1;

这意味着通过ADL找到distance,因此考虑了所有相关的命名空间。如果例如这可能是有问题的。有两个命名空间为distance提供同样适用的重载:

Live On 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);
}

大致有两种方法可以解决它:

  • 从关联的命名空间中删除模糊的qazxsw poi声明(如果竞争的是distancestd::distance,这可能是不可能的)
  • 编辑调用以消除对ADL的依赖(例如,将它们限定为boost::distance或将它们括为std::distance(...)

显示变通方法:

(distance)(...)

Live On Coliru
© www.soinside.com 2019 - 2024. All rights reserved.