c++stlblitz++

Blitz++ arrays as keys for maps


I am trying to use blitz++ arrays, since I understand they generally offer higher performance than other forms of arrays. Is it possible to use blitz++ arrays as keys in a map? Trying

#include <map>
#include <blitz/array.h>
using namespace std;
map<blitz::Array<int,1>,int> testmap;
blitz::Array<int,1> B(3);
B = 1,2,3;
testmap.insert(make_pair(B,2));

does not compile. Here's the error:

In file included from /usr/include/c++/4.6/string:50:0,

/usr/include/c++/4.6/bits/stl_function.h: In member function ‘bool std::less<_Tp>::operator()(const _Tp&, const _Tp&) const [with _Tp = blitz::Array]’:

/usr/include/c++/4.6/bits/stl_function.h:236:22: error: cannot convert ‘blitz::BzBinaryExprResult, blitz::Array >::T_result {aka blitz::_bz_ArrayExpr, blitz::FastArrayIterator, blitz::Less > >}’ to ‘bool’ in return

Is this a matter of requiring a definition of the < operator, and if so, can/should I define it myself?

ANSWER

As suggested by Jimmy Thompson, a possible solution is to define:

struct MyComparison 
{
bool operator() (const blitz::Array<int, 1> &lhs, const blitz::Array<int, 1> &rhs) const 
    {
        if (lhs.size() < rhs.size()) {return true;}
        else if (lhs.size() > rhs.size()) {return false;}
    else
        {
        for (int i=0; i<lhs.size(); i++)
            {
            if (lhs(i)<rhs(i)) {return true;}
            else if(lhs(i)>rhs(i)) {return false;}
            }
        }
    }
};

Then

map<blitz::Array<int,1>,int, MyComparison> testmap;

Solution

  • The std::map documentation states that keys are compared using std::less by default. This just calls < and expects a return of true or false.

    In order for you to use Blitz arrays as a key, you need to do one of the following:

    1. Create your own comparison function, like std::less, which returns a boolean value stating whether one Blitz array is 'less' than the other (how you choose to determine this is up to you). Assuming you made this function and called it MyComparison, you would then create your map as follows map<blitz::Array<int,1>, int, MyComparison> testmap;.

      struct MyComparison
      {
          bool operator() (const blitz::Array<int, 1> &lhs, const blitz::Array<int, 1> &rhs) const
          {
              // Blitz array comparison
          }
      };
      
    2. Wrap your Blitz array type (blitz::Array<int,1>) in another object, overloading the < operator for that given object and then performing your comparison in there. For example:

      class MyArrayWrapper
      {
          blitz::Array<int, 1> contents;
      
      public:
          // Constructor, etc.
      
          bool operator<(const MyArrayWrapper &rhs) const
          {
              // Blitz array comparison
          }
      };
      

    Then in your current file.

        std::map<MyArrayWrapper,int> testmap;