3

I want to have a dimensional agnostic template (usefull for both 3d and 4d), most of operations will be performed on submatrices with first dimension stripped.

So here is what I'd like to have

template <typename element, int dimensions>
class MMapMatrixTemplate{
public:
    typedef boost::multi_array_ref<element, dimensions> array_type; 
    typedef std::array<size_t, dimensions> index_type;
    typedef array_type::array_view<dimensions-1>::type stride_type;
};

Where array_type defines array that is managed by this class index_type defines type used to index arrays, and I'd like `stride_type to define a slice of this array having one less dimension.

For now I get an error:

  include/MMapMatrix.hh:31:55: error: non-template ‘array_view’ used as template
   typedef boost::multi_array_ref<element, dimensions>::array_view<dimensions-1>::type stride_type;
                                                   ^
jb.
  • 23,300
  • 18
  • 98
  • 136
  • possible duplicate of [Where and why do I have to put the "template" and "typename" keywords?](http://stackoverflow.com/questions/610245/where-and-why-do-i-have-to-put-the-template-and-typename-keywords) – Jarod42 Feb 27 '14 at 12:49

2 Answers2

4

You need typename and/or .template qualification on dependent names:

typedef typename array_type::array_view<dimensions-1>::type stride_type;

If you're using a template member on a dependent name, you need .template qualification:

obj.template foo<T>();

See this very popular answer for background

Where and why do I have to put the "template" and "typename" keywords?

Community
  • 1
  • 1
sehe
  • 374,641
  • 47
  • 450
  • 633
4

From the documentation on views, you can see the definition of the view type as:

  typedef typename Array::template array_view<3>::type view1_t;

so this makes your code compile:

#include "boost/multi_array.hpp"

template <typename element, int dimensions>
class MMapMatrixTemplate{
public:

    typedef boost::multi_array_ref<element, dimensions> array_type; 

    typedef std::array<size_t, dimensions> index_type;

    //typedef array_type::array_view<dimensions-1>::type stride_type;
    typedef typename array_type::template array_view<dimensions-1>::type stride_type;
};

int main(int argc, const char *argv[])
{

    typedef MMapMatrixTemplate<double, 4> matrix;

    return 0;
}

You need to specify that the array_view is actually a class template in order to use it as such. Otherwise, the compiler expects it to be fully defined type.

tmaric
  • 5,347
  • 4
  • 42
  • 75