首页 > 解决方案 > 代码不使用特定名称函数编译

问题描述

这段代码不能在我的电脑上编译(用最小的例子编辑):

// Example program
#include <iostream>
#include <string>
#include <vector>
#include <tuple>

template<class PValues>
inline bool equal(PValues it,
                  PValues last,
                  size_t  cols,
                  size_t  rows,

                  size_t offset)
{
  if(std::distance(it,last)<offset)
    return false;

  for(size_t c=0; c<cols; ++c)
    {
      auto p = it + c*rows;
      if(*p != *(p + offset))
        return false;
    }

  return true;
};



int main()
{
  std::vector<std::string> vec = {"1","1","1","2","2","2","3","8","8",
                                  "5","5","2","5","5","5","6","8","8",
                                  "3","3","3","4","4","3","9","8","8"};
  std::vector<double> nbs = {1,2,3,4,5,6,7,8,9};

  auto res = equal(vec.data(), vec.data()+9, 3, 9, 1);
}

我有以下错误:

In file included from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from main.cpp:2:
/usr/include/c++/9/bits/stl_algobase.h: In instantiation of ‘bool std::__equal4(_II1, _II1, _II2, _II2, _BinaryPredicate) [with _II1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _II2 = long unsigned int; _BinaryPredicate = int]’:
/usr/include/c++/9/bits/stl_algobase.h:1219:38:   required from ‘bool std::equal(_IIter1, _IIter1, _IIter2, _IIter2, _BinaryPredicate) [with _IIter1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _IIter2 = long unsigned int; _BinaryPredicate = int]’
main.cpp:60:15:   required from ‘size_t remove_duplicates_rows_impl(PValues, PResults, size_t, size_t) [with PValues = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; PResults = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; size_t = long unsigned int]’
main.cpp:99:32:   required from here
/usr/include/c++/9/bits/stl_algobase.h:1139:13: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<long unsigned int>’
 1139 |       using _Cat2 = typename iterator_traits<_II2>::iterator_category;
      |             ^~~~~
/usr/include/c++/9/bits/stl_algobase.h:1140:13: error: no type named ‘iterator_category’ in ‘struct std::iterator_traits<long unsigned int>’
 1140 |       using _RAIters = __and_<is_same<_Cat1, _RATag>, is_same<_Cat2, _RATag>>;
      |             ^~~~~~~~
/usr/include/c++/9/bits/stl_algobase.h:1144:29: error: no matching function for call to ‘distance(long unsigned int&, long unsigned int&)’
 1144 |    auto __d2 = std::distance(__first2, __last2);
      |                ~~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~
In file included from /usr/include/c++/9/bits/stl_algobase.h:66,
                 from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from main.cpp:2:
/usr/include/c++/9/bits/stl_iterator_base_funcs.h:138:5: note: candidate: ‘template<class _InputIterator> constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator)’
  138 |     distance(_InputIterator __first, _InputIterator __last)
      |     ^~~~~~~~
/usr/include/c++/9/bits/stl_iterator_base_funcs.h:138:5: note:   template argument deduction/substitution failed:
/usr/include/c++/9/bits/stl_iterator_base_funcs.h: In substitution of ‘template<class _InputIterator> constexpr typename std::iterator_traits<_Iterator>::difference_type std::distance(_InputIterator, _InputIterator) [with _InputIterator = long unsigned int]’:
/usr/include/c++/9/bits/stl_algobase.h:1144:29:   required from ‘bool std::__equal4(_II1, _II1, _II2, _II2, _BinaryPredicate) [with _II1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _II2 = long unsigned int; _BinaryPredicate = int]’
/usr/include/c++/9/bits/stl_algobase.h:1219:38:   required from ‘bool std::equal(_IIter1, _IIter1, _IIter2, _IIter2, _BinaryPredicate) [with _IIter1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _IIter2 = long unsigned int; _BinaryPredicate = int]’
main.cpp:60:15:   required from ‘size_t remove_duplicates_rows_impl(PValues, PResults, size_t, size_t) [with PValues = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; PResults = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; size_t = long unsigned int]’
main.cpp:99:32:   required from here
/usr/include/c++/9/bits/stl_iterator_base_funcs.h:138:5: error: no type named ‘difference_type’ in ‘struct std::iterator_traits<long unsigned int>’
In file included from /usr/include/c++/9/bits/char_traits.h:39,
                 from /usr/include/c++/9/ios:40,
                 from /usr/include/c++/9/ostream:38,
                 from /usr/include/c++/9/iostream:39,
                 from main.cpp:2:
/usr/include/c++/9/bits/stl_algobase.h: In instantiation of ‘bool std::__equal4(_II1, _II1, _II2, _II2, _BinaryPredicate) [with _II1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _II2 = long unsigned int; _BinaryPredicate = int]’:
/usr/include/c++/9/bits/stl_algobase.h:1219:38:   required from ‘bool std::equal(_IIter1, _IIter1, _IIter2, _IIter2, _BinaryPredicate) [with _IIter1 = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; _IIter2 = long unsigned int; _BinaryPredicate = int]’
main.cpp:60:15:   required from ‘size_t remove_duplicates_rows_impl(PValues, PResults, size_t, size_t) [with PValues = __gnu_cxx::__normal_iterator<std::__cxx11::basic_string<char>*, std::vector<std::__cxx11::basic_string<char> > >; PResults = __gnu_cxx::__normal_iterator<double*, std::vector<double> >; size_t = long unsigned int]’
main.cpp:99:32:   required from here
/usr/include/c++/9/bits/stl_algobase.h:1153:37: error: invalid type argument of unary ‘*’ (have ‘long unsigned int’)
 1153 |  if (!bool(__binary_pred(*__first1, *__first2)))
      |                                     ^~~~~~~~~
/usr/include/c++/9/bits/stl_algobase.h:1153:25: error: ‘__binary_pred’ cannot be used as a function
 1153 |  if (!bool(__binary_pred(*__first1, *__first2)))

对我来说似乎很奇怪的是:如果我将函数的名称更改为 equalx(或 equalz,只是一个示例),它会编译。该代码不能在 Godbolt 上编译,但可以在 onlinegdb 上编译:https ://onlinegdb.com/ryM5LK4JP 。

我的 g++ 版本:

g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0

行用于编译示例:

g++ -std=c++17 -o main main.cpp

标签: c++g++

解决方案


如果将调用更改为equalfrom equal(first_v, last_v, cols, rows, 1)to
equal(first_v, last_v, cols, rows, size_t(1)),代码将编译。

如果您更改名称,代码编译的原因是有一个名为std::equal. 在重载决议中查看此函数,因为前两个参数std与函数共享名称空间,因此会发生依赖于参数的查找
std::equal可能需要 5 个参数,所有参数都是模板化的,因此将被选为重载决策中的最佳匹配。要使用您的函数,必须进行从intto的隐式转换size_t
通过将最后一个参数更改size_t(1)为调用您的函数不需要进行转换,因此这就是在重载决议中选择的内容。


推荐阅读