I would like to add a operator+ overload to boost::filter_iterator as in below example. However I am getting an error in the resolution of the template parameters to the operator+ overload function.
#include <iostream>
#include <vector>
#include <boost/range/adaptor/filtered.hpp>
template <typename TPredicate, typename TRange>
class Filtered_Range : public boost::filtered_range<TPredicate, TRange>
{
public:
Filtered_Range(TPredicate Predicate, TRange& Range) : boost::filtered_range<TPredicate, TRange>(Predicate, Range) {}
size_t size() const { return std::distance(this->begin(), this->end()); }
auto operator[](size_t Index) const
{
assert(Index < this->size());
auto It = this->begin();
std::advance(It, Index);
return *It;
}
};
template<typename TPredicate, typename TRange>
typename Filtered_Range<TPredicate, TRange>::filter_iterator&
operator+(typename
Filtered_Range<TPredicate, TRange>::filter_iterator& f, int32_t x ) {
std::cout << "Custom overload\n";
return std::advance(f, x);
}
int main() {
const std::vector<int> nums{1, 2, 3, 4, 5, 6, 7, 8, 9};
auto even_only_custom = Filtered_Range([] (auto n) { return (n % 2 == 0); }, nums);
auto x = even_only_custom.begin();
std::cout << "First Value = " << *(x) << "\n";
std::cout << "Second Value = " << *(x + 1); //error here
}
GCC 11.2 error message
<source>: In function 'int main()':
<source>:47:43: error: no match for 'operator+' (operand types are 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' and 'int')
47 | std::cout << "Second Value = " << *(x + 1);
| ~ ^ ~
| | |
| | int
| boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >
<source>:28:1: note: candidate: 'template<class TPredicate, class TRange> typename Filtered_Range<TPredicate, TRange>::filter_iterator& operator+(typename Filtered_Range<TPredicate, TRange>::filter_iterator&, int32_t)'
28 | operator+(typename
| ^~~~~~~~
<source>:28:1: note: template argument deduction/substitution failed:
<source>:47:45: note: couldn't deduce template parameter 'TPredicate'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_algobase.h:67,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/char_traits.h:39,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:568:5: note: candidate: 'template<class _Iterator> constexpr std::reverse_iterator<_Iterator> std::operator+(typename std::reverse_iterator<_Iterator>::difference_type, const std::reverse_iterator<_Iterator>&)'
568 | operator+(typename reverse_iterator<_Iterator>::difference_type __n,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:568:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const std::reverse_iterator<_Iterator>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_algobase.h:67,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/char_traits.h:39,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:1646:5: note: candidate: 'template<class _Iterator> constexpr std::move_iterator<_IteratorL> std::operator+(typename std::move_iterator<_IteratorL>::difference_type, const std::move_iterator<_IteratorL>&)'
1646 | operator+(typename move_iterator<_Iterator>::difference_type __n,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:1646:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const std::move_iterator<_IteratorL>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6094:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
6094 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6094:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:56,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.tcc:1169:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
1169 | operator+(const _CharT* __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.tcc:1169:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const _CharT*' and 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:56,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.tcc:1189:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
1189 | operator+(_CharT __lhs, const basic_string<_CharT, _Traits, _Alloc>& __rhs)
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.tcc:1189:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6131:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, const _CharT*)'
6131 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6131:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6147:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, _CharT)'
6147 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs, _CharT __rhs)
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6147:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6159:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&)'
6159 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6159:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6165:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&, std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
6165 | operator+(const basic_string<_CharT, _Traits, _Alloc>& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6165:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'const std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6171:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
6171 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6171:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6193:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(const _CharT*, std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
6193 | operator+(const _CharT* __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6193:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const _CharT*' and 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6199:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(_CharT, std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&)'
6199 | operator+(_CharT __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6199:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6205:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, const _CharT*)'
6205 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6205:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/string:55,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/locale_classes.h:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/ios_base.h:41,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:42,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6211:5: note: candidate: 'template<class _CharT, class _Traits, class _Alloc> std::__cxx11::basic_string<_CharT, _Traits, _Allocator> std::operator+(std::__cxx11::basic_string<_CharT, _Traits, _Allocator>&&, _CharT)'
6211 | operator+(basic_string<_CharT, _Traits, _Alloc>&& __lhs,
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/basic_string.h:6211:5: note: template argument deduction/substitution failed:
<source>:47:45: note: 'boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >' is not derived from 'std::__cxx11::basic_string<_CharT, _Traits, _Allocator>'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_algobase.h:67,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/char_traits.h:39,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ios:40,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/ostream:38,
from /opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/iostream:39,
from <source>:1:
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:1242:5: note: candidate: 'template<class _Iterator, class _Container> __gnu_cxx::__normal_iterator<_Iterator, _Container> __gnu_cxx::operator+(typename __gnu_cxx::__normal_iterator<_Iterator, _Container>::difference_type, const __gnu_cxx::__normal_iterator<_Iterator, _Container>&)'
1242 | operator+(typename __normal_iterator<_Iterator, _Container>::difference_type
| ^~~~~~~~
/opt/compiler-explorer/gcc-11.2.0/include/c++/11.2.0/bits/stl_iterator.h:1242:5: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const __gnu_cxx::__normal_iterator<_Iterator, _Container>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
In file included from /opt/compiler-explorer/libs/boost_1_67_0/boost/range/iterator_range_core.hpp:27,
from /opt/compiler-explorer/libs/boost_1_67_0/boost/range/iterator_range.hpp:13,
from /opt/compiler-explorer/libs/boost_1_67_0/boost/range/adaptor/filtered.hpp:16,
from <source>:3:
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp:955:3: note: candidate: 'template<class Derived, class V, class TC, class R, class D> typename boost::iterators::enable_if<boost::iterators::detail::is_traversal_at_least<TC, boost::iterators::random_access_traversal_tag>, Derived>::type boost::iterators::operator+(const boost::iterators::iterator_facade<Derived1, V1, TC1, Reference1, Difference1>&, typename Derived::difference_type)'
955 | BOOST_ITERATOR_FACADE_PLUS((
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp:955:3: note: template argument deduction/substitution failed:
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp: In substitution of 'template<class Derived, class V, class TC, class R, class D> typename boost::iterators::enable_if<boost::iterators::detail::is_traversal_at_least<TC, boost::iterators::random_access_traversal_tag>, Derived>::type boost::iterators::operator+(const boost::iterators::iterator_facade<Derived1, V1, TC1, Reference1, Difference1>&, typename Derived::difference_type) [with Derived = boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > >; V = int; TC = boost::iterators::bidirectional_traversal_tag; R = const int&; D = long int]':
<source>:47:45: required from here
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp:955:3: error: no type named 'type' in 'struct boost::iterators::enable_if<boost::iterators::detail::is_traversal_at_least<boost::iterators::bidirectional_traversal_tag, boost::iterators::random_access_traversal_tag>, boost::iterators::filter_iterator<boost::range_detail::default_constructible_unary_fn_wrapper<main()::<lambda(auto:2)>, bool>, __gnu_cxx::__normal_iterator<const int*, std::vector<int> > > >'
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp:960:3: note: candidate: 'template<class Derived, class V, class TC, class R, class D> typename boost::iterators::enable_if<boost::iterators::detail::is_traversal_at_least<TC, boost::iterators::random_access_traversal_tag>, Derived>::type boost::iterators::operator+(typename Derived::difference_type, const boost::iterators::iterator_facade<Derived1, V1, TC1, Reference1, Difference1>&)'
960 | BOOST_ITERATOR_FACADE_PLUS((
| ^~~~~~~~~~~~~~~~~~~~~~~~~~
/opt/compiler-explorer/libs/boost_1_67_0/boost/iterator/iterator_facade.hpp:960:3: note: template argument deduction/substitution failed:
<source>:47:45: note: mismatched types 'const boost::iterators::iterator_facade<Derived1, V1, TC1, Reference1, Difference1>' and 'int'
47 | std::cout << "Second Value = " << *(x + 1);
| ^
Execution build compiler returned: 1
Any pointers on the mistake and possible solutions will be appreciated. Thanks!
In
T is in non-deduced context¹. This means that the only way you can get this to work is by using SFINAE.
Now the overload always participates, but gets discarded by SFINAE for non-filter_iterator arguments:
Live On Coliru
Prints
¹ see also e.g. What is a nondeduced context?
Controlling Instantiations
To limit
operator+support for the custom range subclass only, you have to make the iterator type distinguishable.The "tired" way would be to subclass/wrap the iterator and delegate all of the range interface to work with those instead.
The "wired" way would be wrap the Predicate (which appears as the first template argument for the filter_iterator type!). That way we can look "inside" the filter_iterator's arguments to detect when the predicate is suitably "tagged".
Attempt #1 (Naive)
Now, we decorate the TPredicate in our custom subclass:
And we extend the
is_filt_ittrait to check forTagged<>predicates:Sadly, this breaks:
As you can see, Boost already had a wrapper (at least sometimes) and it breaks our detection
Attempt #2 (Galaxy Brain)
So do we have to get tedious and change the actual iterator type?
No! There's a feature in C++ that is sometimes a little poisonous: Argument dependent lookup. ADL is designed to bring in "associated namespaces" for lookup. Turns out namespaces that declare the types named in template arguments (and their template arguments) are considered "associated".
So:
Nothing changes about
Filtered_Range, and:Now, you have special treatment for iterators from your custom range:
But plain vanilla
boost::filtered_rangedoesn't get special treatment:See it Live: https://godbolt.org/z/xhqjqa3Gc (or correctly not-compiling: https://godbolt.org/z/67vP6TEGc)