This piece of code doesn't compile on my computer (EDIT with minimal example):
// 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);
}
I have the following error :
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)))
What seems strange to me is : if I change the name of the function equal to equalx (or equalz, just an example), it compiles. The code doesn't compile on godbolt to, but it compiles on onlinegdb : https://onlinegdb.com/ryM5LK4JP .
My version of g++ :
g++ (Ubuntu 9.3.0-10ubuntu2) 9.3.0
Line use to compile the example :
g++ -std=c++17 -o main main.cpp
If you change the call to equal
from equal(first_v, last_v, cols, rows, 1)
toequal(first_v, last_v, cols, rows, size_t(1))
, the code compiles.
The reason the code compiles if you change the name is that there's a standard algorithm named std::equal
. This function is looked at in overload resolution because the first two arguments share the std
namespace with the function, so argument-dependent lookup happens.std::equal
may take 5 arguments, all of which are templated, so that will be selected as the best match in overload resolution. To use your function, there would have to be an implicit conversion from int
to size_t
.
By changing the last parameter to size_t(1)
there's no conversion necessary to call your function, thus that is what is selected in overload resolution.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With