我想将operator+重载添加到boost::filter_iterator中,如下例所示。但是,在将模板参数解析为operator+重载函数时,我得到了一个错误。
#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错误消息
<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任何关于错误和可能的解决方案的建议都将不胜感激。谢谢!
发布于 2022-02-20 22:55:11
在……里面
template <typename T>
void foo(typename T::nested_type) {}T在非推断语境中。这意味着,只有使用SFINAE才能使其工作。
namespace detail {
template <typename T> struct is_filt_it : std::false_type { };
template <typename... Args>
struct is_filt_it<boost::filter_iterator<Args...>> : std::true_type { };
} // namespace detail
template <typename It>
static decltype(auto) operator+(It it, std::enable_if_t<detail::is_filt_it<It>::value, int32_t> x)
{
return std::next(it, x);
}现在,重载总是参与,但是对于非filter_iterator参数,SFINAE会丢弃:
住在Coliru
#undef NDEBUG
#include <boost/range/adaptor/filtered.hpp>
#include <iostream>
#include <vector>
template <typename TPredicate, typename TRange>
struct Filtered_Range : boost::filtered_range<TPredicate, TRange> {
using base_type = boost::filtered_range<TPredicate, TRange>;
using base_type::base_type;
auto operator[](size_t i) const {
assert(i < this->size());
return *std::next(base_type::begin(), i);
}
};
template <typename TPredicate, typename TRange>
Filtered_Range(TPredicate const&, TRange const&) -> Filtered_Range<TPredicate, TRange>;
namespace detail {
template <typename T> struct is_filt_it : std::false_type { };
template <typename... Args>
struct is_filt_it<boost::filter_iterator<Args...>> : std::true_type { };
} // namespace detail
template <typename It>
static decltype(auto) operator+(It it, std::enable_if_t<detail::is_filt_it<It>::value, int32_t> x)
{
return std::next(it, x);
}
int main() {
std::vector nums{1, 2, 3, 4, 5, 6, 7, 8, 9};
auto evens = Filtered_Range([](auto n) { return (n % 2 == 0); }, nums);
auto it = evens.begin();
std::cout << "First Value = " << *(it) << "\n";
std::cout << "Second Value = " << *(it + 1) << "\n";
}打印
First Value = 2
Second Value = 4也见例如什么是非推断的语境?
控制实例
要限制对自定义范围子类的operator+支持,必须使迭代器类型区分开来。
“累”的方法是对迭代器进行子类/包装,并委托所有的范围接口来处理这些接口。
“有线”方式将是对谓词进行包装(作为filter_iterator类型的第一个模板参数出现!)。这样,我们就可以查看filter_iterator的参数,以检测谓词何时被适当地“标记”。
第一次尝试(天真)
namespace MyLib {
template <typename F> struct Tagged : F {
Tagged(F f) : F(std::move(f)) {}
using F::operator();
};
} // namespace MyLib现在,我们在自定义子类中装饰TPredicate:
template <typename TPredicate, typename TRange>
struct Filtered_Range : boost::filtered_range<MyLib::Tagged<TPredicate>, TRange> {
using base_type = boost::filtered_range<MyLib::Tagged<TPredicate>, TRange>;
using base_type::base_type;
auto operator[](size_t i) const {
assert(i < this->size());
return *std::next(base_type::begin(), i);
}
using const_iterator = typename boost::range_iterator<base_type, void>::type;
};我们扩展了is_filt_it特性以检查Tagged<>谓词:
namespace detail {
template <typename T> struct is_tagged : std::false_type { };
template <typename F> struct is_tagged<MyLib::Tagged<F>> : std::true_type { };
template <typename T, typename = void> struct is_filt_it : std::false_type { };
template <typename F, typename... Args>
struct is_filt_it<boost::filter_iterator<F, Args...>,
std::enable_if_t<is_tagged<F>::value>> : std::true_type {
};
} // namespace detail可悲的是,这打破了:
候选模板被忽略: requirement 'detail::is_filt_it,bool>.
如您所见,Boost已经有了一个包装器(至少有时如此),它破坏了我们的检测。
第二次尝试(银河大脑)
那么,我们是否有使变得乏味,并改变实际的迭代器类型?
不是的!C++中有一项功能有时有点麻烦:依赖于参数的查找。ADL旨在引入“关联名称空间”以进行查找。结果表明,声明模板参数中命名的类型(及其模板参数)的命名空间被认为是“关联的”。
所以:
namespace MyLib {
namespace AdlBarrier {
template <typename F> struct Tagged : F {
Tagged(F f) : F(std::move(f)) {}
using F::operator();
};
template <typename T> constexpr bool is_tagged(T&&) { return true; }
} // namespace AdlBarrier
using AdlBarrier::Tagged;
} // namespace MyLibFiltered_Range没有任何变化,而且:
namespace detail {
template <typename T, typename = void> struct is_filt_it : std::false_type { };
template <typename F, typename... Args>
struct is_filt_it<boost::filter_iterator<F, Args...>,
std::enable_if_t<is_tagged(static_cast<F*>(nullptr))>>
: std::true_type {
};
} // namespace detail现在,您可以对来自自定义范围的迭代器进行特殊处理:
{
auto evens = Filtered_Range([](auto n) { return (n % 2 == 0); }, nums);
auto it = evens.begin();
std::cout << "First Value = " << *(it) << "\n";
std::cout << "Second Value = " << *(it + 1) << "\n";
}但普通香草boost::filtered_range没有得到特殊待遇:
{
auto odds = boost::filtered_range([](auto n) { return (n % 2 == 1); }, nums);
auto it = odds.begin();
std::cout << "First Value = " << *(it) << "\n";
std::cout << "Second Value = " << *(it + 1) << "\n"; // doesn't compile
}查看it Live:https://godbolt.org/z/xhqjqa3Gc (或正确地不编译:https://godbolt.org/z/67vP6TEGc)
https://stackoverflow.com/questions/71190418
复制相似问题