0

I am fairly new to template metaprogramming in C++ and this is a homework assignment.

I am trying to write a multidimensional variadic template array, where I have to expose an operator[] of the following form:

Array<int, 2, 2, 3, 3> a1;   // 4D array of ints
a1[0][0][0][0] = 10;         // insert 10 
a1[1][1][1][1] = 100;        // insert 100 
                             // and so on

The trouble is, I am not able to decipher the error messages and I am clueless. I have tried looking at some hacks such as int*** i = some_T; to learn more about the types as they are instantiated.

Question: I am not able to understand what should be returned in the operator[] overload in the recursive case. Is there something wrong with the way I am using multiple inheritance?

The code:

array.hpp

#ifndef ARRAY_HPP
#define ARRAY_HPP

    template<typename T, size_t sz>
      class Data {
        public:
          Data() : len(sz) {}
          T m_data[sz];
          const size_t len;
      };

/* declaration */
template<typename T, size_t... Dims>
  class Array;

/* Base case */
template<typename T, size_t Dim>
  class Array<T, Dim> : public Data<T, Dim> {
    public:
      explicit Array() {} 

      T & operator[](size_t i) {
        return Data<T, Dim>::m_data[i];
      }   
   };

/* Rec case */
template<typename T, size_t Dim, size_t... Dims>
  class Array<T, Dim, Dims...> : public Data<T, Dim>, public Array<T, Dims...> {
    public:
      explicit Array() {}    

      Array<T, Dims...> & operator[](size_t i) {
        return Data<T, Dim>::m_data[i];
      }
   };

#endif

driver.cpp

#include <iostream>
#include "array.hpp"

int main() {
  Array<int, 2, 2> a1;

  /* add elements */
  int counter = 0;
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      a1[i][j] = counter++;
    }
  }

  /* print elements */
  for (int i = 0; i < 2; ++i) {
    for (int j = 0; j < 2; ++j) {
      std::cout << a1[i][j] << '\n';
    }
  }

  return 0;
}

error

clang++ -std=c++11 -stdlib=libc++ driver.cpp 
In file included from driver.cpp:2:
./array.hpp:34:16: error: ambiguous conversion from derived class
  'Array<int, 2, 2>' to base class 'Data<int, 2>':
class Array<int, 2, 2> -> Data<int, 2UL>
class Array<int, 2, 2> -> Array<int, 2UL> -> Data<int, 2UL>
    return Data<T, Dim>::m_data[i];
           ^~~~
driver.cpp:10:13: note: in instantiation of member function 'Array<int, 2,
  2>::operator[]' requested here
      a1[i][j] = counter++;
        ^

1 error generated.

qurrat
  • 1
  • 1
  • @Barry I tried following the approach in [this question](http://stackoverflow.com/questions/30155608/arbitrary-dimensional-array-using-variadic-templates), and trying to return a reference to an array of size one less. But I am not able to understand the type mismatch. – qurrat May 11 '15 at 22:22
  • Your recursive case shouldn't inherit from `Data`. The compiler error message is very helpful in this case. Draw the hierarchy and you'll see why. – Barry May 11 '15 at 22:43

0 Answers0