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
  • 42,521
  • 11
  • 108
  • 141
atefsawaed
  • 258
  • 1
  • 10
  • 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
  • 220,365
  • 33
  • 331
  • 451
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
  • 39,010
  • 10
  • 84
  • 149
1

You are almost there:

return const_cast<T&>(const_cast<const Matrix*>(this)->operator()(row, col));
Igor Tandetnik
  • 45,980
  • 4
  • 51
  • 75