null
null

Reputation: 111

Error: invalid conversion from 'const int*' to 'int*'

I want to create a simple 3x3 matrix class and be able to access its contents by the subscript operator. Here's the code:

// Matrix.h
class Matrix {
private:
    int matrix[3][3];
public:
    int* operator[](const int index) const;
};

// Matrix.cpp
int* Matrix::operator[](const int index) const {
    return this->matrix[index];
}

I want to be able to access the elements of the array no matter whether the Matrix's object is const or non-const. But I get the following error from the compiler:

error: invalid conversion from 'const int*' to 'int*' [-fpermissive]

I did some research and I have a hypothesis: maybe, because I have declared this member function as a const function, inside its definition the compiler treats (it masks) all of the the object's non-mutable members as const members, so that would be the reason the compiler says it's an invalid conversion from 'const int*' to 'int*'. My question: Is this hypothesis correct? And if it's not, why does that happens? I think it makes sense and would be a great way of ensuring the const-ness of the 'const Matrix *this' object.

Compiler Info: gcc 5.3.0 downloaded from equation.com

Upvotes: 4

Views: 4970

Answers (6)

Zubair Azami
Zubair Azami

Reputation: 65

hope this helps:

#include<iostream>
using namespace std;

class Matrix
{
private:
    int matrix[3][3];
public:
    const int* operator[](const int index) const;
    Matrix(int* value); // need an initializer though :)
};

const int* Matrix::operator[](const int index) const
{
    return this->matrix[index];
}

Matrix::Matrix(int* value)
{
    for(int i=0; i<3;i++)
    {
        for (int j=0; j<3; j++)
        {
            matrix[i][j]= *value;
            value++;
        }
    }
}

int main( void )
{
    int arr[] = {1,2,3,4,5,6,7,8,9};
    Matrix C(arr);

    const int *c;
    c = C[0];

    for(int i=0;i<3;i++)
    {
        cout << *c << ends;
        c++;
    }
    return 0;
}

Upvotes: 0

vladon
vladon

Reputation: 8401

Change this:

int* Matrix::operator[](const int index) const

to this

const int* Matrix::operator[](const int index) const

You cannot return mutable pointer to data member from const function.

Or you may create two versions of operator: const and non const:

const int* Matrix::operator[](const int index) const;
int* Matrix::operator[](const int index);

PS. And anyway it's a very bad practice to return pointer or reference to internal class members.

Upvotes: 0

Humam Helfawi
Humam Helfawi

Reputation: 20264

You are getting this error because you are return a pointer from a const member function (or operator).

const member function and operator should not change any non-mutable member neither return pointers that can change them later.

Make your operator return const pointer rather than pointer.

class Matrix {
private:
    int matrix[3][3];
public:
    int const* operator[](const int index) const;
};

// Matrix.cpp
int const* Matrix::operator[](const int index) const {
    return this->matrix[index];
}

Live Demo

Upvotes: 0

Sergey Kalinichenko
Sergey Kalinichenko

Reputation: 726579

You are absolutely right about the reason why you get the error: inside a member function marked const the compiler implicitly treats all data members of the class as if they were declared with a const qualifier.

The fix is really straightforward - you can override the same operator twice, providing a const and a non-const versions:

class Matrix {
private:
    int matrix[3][3];
public:
    const int* operator[](const int index) const;
    int* operator[](const int index);
};

// Matrix.cpp
const int* Matrix::operator[](const int index) const {
    return this->matrix[index];
}
int* Matrix::operator[](const int index) {
    return this->matrix[index];
}

The compiler will figure out which overload to call based on the context. It will call const version if the Matrix itself is const, and the non-const version otherwise.

Upvotes: 4

Jakub Zaverka
Jakub Zaverka

Reputation: 8874

When you declare a class method (and operator is a class method) const, that means you can only call const methods on your class's fields and return only const pointers or references to class fields. In order to compile, you need to make up your mind to have either:

const int* Matrix::operator[](const int index) const { return this->matrix[index]; }

or

int* Matrix::operator[](const int index) { return this->matrix[index]; }

or both.

Upvotes: 3

Giorgi Moniava
Giorgi Moniava

Reputation: 28654

int* Matrix::operator[](const int index) const {
    return this->matrix[index]; }

Here you say you don't modify the state of your object by specifying function as const.

But you are returning a pointer to your instance variable - and through that pointer it is possible to change value of the instance variable of your class (and thus the state).

So you can create a non const version of that operator to avoid that issue.

Upvotes: 2

Related Questions