3

I want to search for a small image from a large one, my algorithm is:

  1. search for the first line
  2. if first line matches, then compare the rest

I want to use boost::algorithm::boyer_moore to do the line searching, it works fine with std::string:

#include <string>
using namespace std;
#include "boost/algorithm/searching/boyer_moore.hpp"
using namespace boost::algorithm;

int main() {
    string s;

    boyer_moore<string::iterator> bm(s.begin(), s.end()); // it compiles
}

the code compiles, but this one not:

#include "boost/mpl/vector.hpp"
using namespace boost;
#include "boost/gil/gil_all.hpp"
using namespace boost::gil;

#include "boost/algorithm/searching/boyer_moore.hpp"
using namespace boost::algorithm;

int main() {
    typedef rgba8_image_t image_t;
    typedef image_t::view_t view_t;

    view_t vw;

    boyer_moore<view_t::x_iterator> bm(vw.row_begin(0), vw.row_end(0)); // compile error
}

Both of them are iterators, what's wrong with the second one?

Thanks.

pmr
  • 58,701
  • 10
  • 113
  • 156
aj3423
  • 2,003
  • 3
  • 32
  • 70
  • 1
    It's highly unusual to distort includes by doing `using namespace` before including them, especially so with TMP-heavy libraries (because they will often rely on ADL for name lookups) – sehe Jun 23 '14 at 11:18
  • By the way, the tag [tag:gil] is not related to Boost.GIL. The tag you want is [tag:boost-gil]. You should change it in order to maximize the probability of your question reaching an expert in the library. – llonesmiz Jun 23 '14 at 11:28

1 Answers1

4

According to the docs the algorithm uses an auxiliary data structure called skip_table. By default (when the value_type of the iterator is not a char or unsigned char) this table uses a tr1::unordered_map, and this requires that gil::pixel be hash-able. So you have two options: you either change the default skip_table by specializing BM_traits for your iterator (this is sadly undocumented), or you make gil::pixel hash-able. For the latter you can create a std::size_t hash_value(pixel<ChannelValue,Layout> const& val) inside the namespace boost::gil. The following compiles with g++ 4.9.0 and Visual Studio 2013 (and does nothing):

#include <boost/functional/hash.hpp> //ADDED
#include <boost/mpl/vector.hpp>
#include <boost/gil/gil_all.hpp>
#include <boost/algorithm/searching/boyer_moore.hpp>

using namespace boost;
using namespace boost::gil;
using namespace boost::algorithm;

namespace boost {
    namespace gil
    {
        template <typename ChannelValue, typename Layout>
        std::size_t hash_value(pixel<ChannelValue, Layout> const& b)
        {
            std::size_t seed = 0;
            for (int c = 0; c<num_channels<pixel<ChannelValue, Layout> >::value; ++c)
                hash_combine(seed, b[c]);
            return seed;
        }
    }
}

namespace std { //ADDED
    template <typename ChannelValue, typename Layout>
    struct hash<boost::gil::pixel<ChannelValue,Layout> > {
        size_t operator ()(boost::gil::pixel<ChannelValue, Layout> const& value) const {
            return hash_value(value);
        }
    };
}

int main() {
    typedef rgba8_image_t image_t;
    typedef image_t::view_t view_t;

    view_t vw;

    boyer_moore<view_t::x_iterator> bm(vw.row_begin(0), vw.row_end(0)); // compile error
}
llonesmiz
  • 155
  • 2
  • 11
  • 20
  • Thanks, but the code still not compile with vs2010, here's the output: [link](http://pastebin.com/aS5NWUss) – aj3423 Jun 23 '14 at 10:48
  • 1
    Following [this](http://stackoverflow.com/questions/14813965/how-to-specialize-stdhash-for-type-from-other-library) and [this](http://stackoverflow.com/a/24362641/2417774) I have edited the code. It now also compiles with vs2013, hope it also works for you. – llonesmiz Jun 23 '14 at 11:20
  • Works for vs2013. Thanks. – aj3423 Jun 23 '14 at 13:46