5

A range can be used to slice a Boost Multidimensional array (multi_array). According to the documentation there are several ways of defining a range, however not all of them will compile. I'm using GCC 4.5.2 on Ubuntu 11.04.

#include <boost/multi_array.hpp>

int main() {
    typedef boost::multi_array_types::index_range range;
    range a_range;   

    // indices i where 3 <= i

    // Does compile
    a_range = range().start(3);

    // Does not compile
    a_range = 3 <= range();
    a_range = 2 < range();

    return 0;
}

The compiler output is:

ma.cpp: In function ‘int main()’:
ma.cpp:9:26: error: no match for ‘operator<=’ in ‘3 <= boost::detail::multi_array::index_range<long int, long unsigned int>()’
ma.cpp:10:25: error: no match for ‘operator<’ in ‘2 < boost::detail::multi_array::index_range<long int, long unsigned int>()’

Any idea how I can compile this, or what is missing?

YXD
  • 31,741
  • 15
  • 75
  • 115
  • have you tried explicitly injecting the entire namespace (i.e. `using boost::deail::multi_array`)? This is where the operators appear to be defined, however maybe with your compiler ADL is failing (ideone for example compiles the above). – Nim Jul 07 '11 at 15:24
  • tried `using namespace boost::detail::multi_array` and I still get the error... – YXD Jul 07 '11 at 15:30
  • `dpgk` says version 1.42.0. Can't see any relevant [tickets](https://svn.boost.org/trac/boost) or anything in the [changelog](http://www.boost.org/doc/libs/1_46_1/doc/html/unordered/changes.html). – YXD Jul 07 '11 at 15:44
  • Strange, have just ssh'ed into another machine and it compiles there. Currently checking what's different on there. – YXD Jul 07 '11 at 15:51
  • Other machine has Boost 1.33.0 and GCC 4.1.2. – YXD Jul 07 '11 at 15:54
  • 1
    btw. 1.42. is not certified with 4.5.2 - so there could be some issues there, only 1.46 is certified with 4.5.2 – Nim Jul 07 '11 at 16:02

1 Answers1

5

The operator< and operator<= being invoked here are templates; consequently, the value supplied to said operators for the Index argument must be the exact same type as the Index template parameter of the range being supplied.

The boost::multi_array_types::index_range::index type ultimately boils down to a typedef for std::ptrdiff_t; given that you're supplying int literals, clearly for your platform/configuration, std::ptrdiff_t is a typedef for some type other than int (according to your error messages it's long).

The portable fix is to coerce your literals to the proper type:

#include <boost/multi_array.hpp>

int main()
{
    typedef boost::multi_array_types::index_range range;
    typedef range::index index;

    range a_range;
    a_range = index(3) <= range();
    a_range = index(2) < range();

    index i(1);
    a_range = i <= range();
}
ildjarn
  • 62,044
  • 9
  • 127
  • 211