Stijn
Stijn

Reputation: 35

Array as map key

I'm trying to use an array as map key. I got it working but as soon as I try to integrate it in a class I'm getting the following compiler error:

In instantiation of ‘T& Matrix::operator[](std::array) [with T = double]’: 35:12: required from here 20:24: error: no match for call to ‘(std::map, double, std::less >, std::allocator, double> > >) (const std::array&)’ return matrix(index);

This is what my code looks like:

#include <map>

template <typename T>
struct Matrix{
    std::map<std::array<int,2>,T> matrix;
    int rows;
    int columns;

    Matrix()
    : rows(0),
      columns(0)
    {  }

    Matrix(int rows,int columns)
    :  rows(rows),
    columns(columns)
    { }

    T& operator[](const std::array<int,2> index){
    return matrix(index);
}

    T& operator[](const std::array<int,2>& index) const{
    return matrix(index);
}

};

int main(int argc, char *argv[])
{
    Matrix<double> M(10,10);
    double a = 10;
    M[{10,11}] = a;


    return 0;
}

Upvotes: 2

Views: 786

Answers (3)

rustyx
rustyx

Reputation: 85286

Like the error message says, the problem is here:

    return matrix(index);

It should be:

    return matrix[index];

Notice the [] operator.

Also matrix[index] can't be called in a const context since in C++ map::operator[] creates missing elements, and so is a potentially mutating operation. I would re-think your design, otherwise there will be discrepancy between how your non-const [] and const [] behave with regard to missing keys.

Note: you should also #include <array>.


P.S. The compare operator for std::array is provided.

Upvotes: 2

Vlad from Moscow
Vlad from Moscow

Reputation: 310950

In these operators

T& operator[](const std::array<int,2> index){
return matrix(index);
}

T& operator[](const std::array<int,2>& index) const{
return matrix(index);
}

you are trying to call a non-existent operator function of the class template std::map

matrix(index)

It is evident you mean in the first subscript operator

matrix[index]

T& operator[](const std::array<int,2> &index){
return matrix[index];
}

and in the second subscript operator the member function at.

const T& operator[](const std::array<int,2>& index) const{
return matrix.at(index);
}

Also the second operator should be declared with the returned type qualified with the qualifier const that is it should return a constant reference because the member function is in turn a constant function.

Upvotes: 2

user12831477
user12831477

Reputation:

You have some problems in your code:

  • missing include for array (works with gcc but not with clang)
  • usage of missing call operator
  • usage of copies instead of const references
#include <array> // Added include
#include <map>

template <typename T>
struct Matrix{
    std::map<std::array<int,2>,T> matrix;
    int rows;
    int columns;

    Matrix()
    : rows(0),
      columns(0)
    {  }

    Matrix(int rows,int columns)
    :  rows(rows),
    columns(columns)
    { }

    T& operator[](const std::array<int,2> &index){
        return matrix[index]; // replace call operator
    }

    const T& operator[](const std::array<int,2> &index) const{ //return const reference
        return matrix.at(index); // replace call operator
    }

};

int main(int argc, char *argv[])
{
    Matrix<double> M(10,10);
    double a = 10;
    M[{10,11}] = a;


    return 0;
}

Upvotes: 1

Related Questions