0

I have a generic Matrix class, and I have two version of operator(), a const method that returns a const reference to the index, and a non-const method that returns a non const reference to the index (which allows me to change it.

I tried to use the non-const version by using const_cast and calling for the const version, but for some reason it doesn't work:

template<typename T>
class Matrix
{

    std::vector<T> _matrix;
    unsigned int _rows;
    unsigned int _cols;
 public:
    const T& operator()(unsigned int row, unsigned int col) const
    {
        return _matrix[col + (_cols * row)];
    }

    T& operator()(unsigned int row, unsigned int col)
    {
    return const_cast<T&>(static_cast<const Matrix*> (*this).operator(row, col));
    }
};

It doesn't allow me to add the (row, col) to the operator in the last line. Any ideas?

3

3 Answers 3

6

Here, code duplication is the lesser of the two evils. Simply repeat the expression _matrix[col + (_cols * row)] in the non-const version. Don't fight the language.

To call the const version, you need to const_cast the this pointer. The expression you were after was const_cast<T&>(const_cast<const Matrix*>(this)->operator()(row, col)); which is considerably more difficult to read and does contain an unnerving const_cast; twice.

Sign up to request clarification or add additional context in comments.

Comments

4

In my humble opinion this is not a case where you want to avoid code duplication. So I suggest the following:

const T& operator()(unsigned int row, unsigned int col) const {
  return _matrix[col + (_cols * row)];
}

T& operator()(unsigned int row, unsigned int col) {
  return _matrix[col + (_cols * row)];
}

It's also more readable than the version with the const_cast and potentially faster as you avoid an unnecessary stack frame.

Comments

1

You are almost there:

return const_cast<T&>(const_cast<const Matrix*>(this)->operator()(row, col));

1 Comment

Upvoted: you figured out the expression 2 minutes before I did.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.