c++ - 代码不使用特定名称函数编译
问题描述
这段代码不能在我的电脑上编译(用最小的例子编辑):
// 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
解决方案
如果将调用更改为equal
from 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 个参数,所有参数都是模板化的,因此将被选为重载决策中的最佳匹配。要使用您的函数,必须进行从int
to的隐式转换size_t
。
通过将最后一个参数更改size_t(1)
为调用您的函数不需要进行转换,因此这就是在重载决议中选择的内容。
推荐阅读
- tensorflow - 模型训练期间不可打印的字符
- pentaho-report-designer - pentaho 报表设计器中的动态数据库连接
- captcha - 站点所有者的错误:站点密钥的域无效我在一个域中设置了两个网站
- python - 如何用零替换不平衡数据框中的缺失值?
- pine-script - 如何在 Pine Script 中填充不同分辨率数据的绘图?
- swift - SwiftUI 中的 body 由什么结构组成?
- summernote - Summernote 编辑器显示两克拉的下拉菜单
- react-native - WARN 在 React Native 中没有为键 ReactNativeFirebaseMessagingHeadlessTask 注册任务?
- javascript - 如何在 SVG 中绘制清晰的 1px 线条(使用 js)?
- python - 用于共指解析的 Corefgraph