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?

Rakete1111
  • 47,013
  • 16
  • 123
  • 162
atefsawaed
  • 543
  • 8
  • 14
  • 3
    Possible duplicate of [How do I remove code duplication between similar const and non-const member functions?](http://stackoverflow.com/questions/123758/how-do-i-remove-code-duplication-between-similar-const-and-non-const-member-func) – Garf365 Oct 03 '16 at 12:58
  • Make a macro. You still get code duplication, but you can hide 50% of it. – UKMonkey Oct 03 '16 at 13:23
  • You avoid code duplication by adding twice as much code, and make it more complicated. Doesn't seem like a win to me. – Bo Persson Oct 03 '16 at 13:40

3 Answers3

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.

Bathsheba
  • 231,907
  • 34
  • 361
  • 483
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.

101010
  • 41,839
  • 11
  • 94
  • 168
1

You are almost there:

return const_cast<T&>(const_cast<const Matrix*>(this)->operator()(row, col));
Igor Tandetnik
  • 50,461
  • 4
  • 56
  • 85