Pregunta

I run into problems with boost::adaptors::filtered. There is a sample for demonstrating the problem

struct IsRegex { 
  IsRegex() {} // filter_iterator requires default constructible predicate
  explicit IsRegex(const boost::regex &rx) : m_rx(rx) {}
  IsRegex(const IsRegex &isRegex) : m_rx(isRegex.m_rx) {}
  void swap(IsRegex &isRegex) { std::swap(m_rx, isRegex.m_rx); }
  IsRegex& operator=(IsRegex isRegex) { swap(isRegex); return *this; }

  bool operator() (const std::string &str) const {
    return boost::regex_match(str, m_rx);
  }
  boost::regex m_rx;
};

int main()
{
   std::string foo[] = {"0ii", "22", "48", "555", "15", "ab"};
   typedef std::list<std::string> Container;
   Container bar((foo), foo+5);
   const boost::regex rx(("\\d{2}"));
   IsRegex isRegex((rx));
   Container::iterator it 
         = boost::max_element(bar | boost::adaptors::filtered(isRegex));
}

Unfortunately, I've got

In function ‘int main()’:
error: conversion from 
‘boost::filter_iterator< IsRegex, std::_List_iterator<std::string> >’
to non-scalar type 
‘std::_List_iterator<std::string>’
requested

What the reason of this behavior and how to work around it?

¿Fue útil?

Solución

You want to map the source iterator from the adapted iterator with .base():

Container::iterator it = 
     boost::max_element(bar | boost::adaptors::filtered(isRegex))
     .base();

Also, may I suggest fixing the naming of your predicate to say what it means:

#include <boost/range/adaptors.hpp>
#include <boost/range/algorithm.hpp>
#include <list>

using namespace boost::adaptors;

struct IsMatch { 
    IsMatch(const boost::regex &rx = boost::regex()) : m_rx(rx) {}

    bool operator() (const std::string &str) const {
        return boost::regex_match(str, m_rx); 
    }
  private:
    boost::regex m_rx;
};

int main()
{
    std::string foo[] = {"0ii", "22", "48", "555", "15", "ab"};

    typedef std::list<std::string> Container;
    Container const bar(foo, foo+5);

    IsMatch isMatch(boost::regex("\\d{2}"));

    Container::const_iterator it = boost::max_element(bar | filtered(isMatch)).base();
}
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top