atefsawaed
atefsawaed

Reputation: 601

Avoid code duplication by implementing two functions that differ by const

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?

Upvotes: 0

Views: 99

Answers (3)

Dimitrios Bouzas
Dimitrios Bouzas

Reputation: 42929

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.

Upvotes: 4

Bathsheba
Bathsheba

Reputation: 234775

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.

Upvotes: 6

Igor Tandetnik
Igor Tandetnik

Reputation: 52581

You are almost there:

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

Upvotes: 1

Related Questions