Как перегрузить оператор вызова функции в зависимости от того, вызывается ли она слева или справа

Можно ли перегрузить оператор вызова функции, чтобы:

  • когда вызывающая сторона находится в левой части выражения, всегда вызывается непостоянная версия
  • когда вызывающая сторона находится в правой части выражения, всегда вызывается константная версия

?

Я все еще изучаю C++ и вчера провел несколько часов в Интернете, чтобы разобраться в этом. ChatGPT и некоторые другие ответы здесь предполагают, что это будет возможно с использованием трюка с использованием вспомогательного или прокси-класса, но это, похоже, влечет за собой создание такого объекта каждый раз, когда мойназывается. Мне интересно, возможно ли это менее затратным способом. Я знаю, что для решения этой проблемы можно просто использовать метод получения констант, но мне интересно узнать больше о перегрузке операторов.

Вот игрушечная программа (надеюсь), чтобы прояснить ситуацию:

      #include <iostream>
#include <vector>

// Implements a matrix. There are two arrays, a 'previous' and a 'current' one,
// to read the previous state from and to write the updated state into. Reading
// should always be from the 'previous' array and writing should always be to
// the 'current' array. The pointers to these arrays can be swapped.
class Matrix {
private:
    // matrix dimensions
    const int m_width;
    const int m_height;
    // arrays
    std::vector<double> m_arr1;
    std::vector<double> m_arr2;
    // 'current' and 'previous' pointers to arrays
    std::vector<double>* m_curr;
    std::vector<double>* m_prev;
public:
    Matrix(const int width, const int height)
        :
        m_width{width}, m_height{height},
        m_arr1(width*height, 0.0), m_arr2(width*height, 0.0),
        m_curr{&m_arr1}, m_prev{&m_arr2}
    {}
    // non-const version which I would always want to be called from the left-hand side
    double& operator()(const int i, const int j) {
        std::cout << "write to (" << i << ", " << j << ")" << std::endl;
        return (*m_curr)[m_width*j + i];
    }
    // const version which I would always want to be called from the right-hand side
    const double& operator()(const int i, const int j) const {
        std::cout << "read from (" << i << ", " << j << ")" << std::endl;
        return (*m_prev)[m_width*j + i];
    }
    void swap() {
        std::cout << "swap" << std::endl;
        std::vector<double>* temp{m_curr};
        m_curr = m_prev;
        m_prev = temp;
    }
};

int main()
{
    Matrix A{2, 2};
    A(1, 0) = -1;           // writes to 'current' array ('m_arr1')
    A.swap();               // arrays are swapped
    A(1, 0) = 3 + A(1, 0);  // I wish this would write to 'current' array ('m_arr2') from 'previous' array ('m_arr1')
    return 0;
}

Проблема здесь в том, что, поскольку мои экземпляры «Матрицы» обычно не, постоянная версия не вызывается. Есть ли способ вызвать константную версию с правой стороны без создания вспомогательных или прокси-объектов? Спасибо!

0 ответов

Другие вопросы по тегам