首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >扩展boost的迭代器::过滤以支持operator+重载

扩展boost的迭代器::过滤以支持operator+重载
EN

Stack Overflow用户
提问于 2022-02-20 00:37:10
回答 1查看 50关注 0票数 1

我想将operator+重载添加到boost::filter_iterator中,如下例所示。但是,在将模板参数解析为operator+重载函数时,我得到了一个错误。

代码语言:javascript
复制
#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错误消息

代码语言:javascript
复制
<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

任何关于错误和可能的解决方案的建议都将不胜感激。谢谢!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-02-20 22:55:11

在……里面

代码语言:javascript
复制
template <typename T>
    void foo(typename T::nested_type) {}

T在非推断语境中。这意味着,只有使用SFINAE才能使其工作。

代码语言:javascript
复制
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

代码语言:javascript
复制
#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";
}

打印

代码语言:javascript
复制
First  Value = 2
Second Value = 4

也见例如什么是非推断的语境?

控制实例

要限制对自定义范围子类的operator+支持,必须使迭代器类型区分开来。

“累”的方法是对迭代器进行子类/包装,并委托所有的范围接口来处理这些接口。

“有线”方式将是对谓词进行包装(作为filter_iterator类型的第一个模板参数出现!)。这样,我们就可以查看filter_iterator的参数,以检测谓词何时被适当地“标记”。

第一次尝试(天真)

代码语言:javascript
复制
namespace MyLib {
    template <typename F> struct Tagged : F {
        Tagged(F f) : F(std::move(f)) {}
        using F::operator();
    };
} // namespace MyLib

现在,我们在自定义子类中装饰TPredicate:

代码语言:javascript
复制
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<>谓词:

代码语言:javascript
复制
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旨在引入“关联名称空间”以进行查找。结果表明,声明模板参数中命名的类型(及其模板参数)的命名空间被认为是“关联的”。

所以:

代码语言:javascript
复制
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 MyLib

Filtered_Range没有任何变化,而且:

代码语言:javascript
复制
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

现在,您可以对来自自定义范围的迭代器进行特殊处理:

代码语言:javascript
复制
{
    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没有得到特殊待遇:

代码语言:javascript
复制
{
    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)

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/71190418

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档