Реализация A (:, k) = b; Matlab-подобный синтаксис в матричной библиотеке C ++

Я разработал собственный матричный класс C ++ на основе шаблонов выражений. Я перегрузил оператор (), чтобы я мог читать или записывать матрицы элементов, например,

cout << A(i,j) << endl;

а также

A(i,j)=b;

соответственно. Я также реализовал класс Range, чтобы разрешить чтение в стиле Matlab как

cout << A(Range(3,5),Range(0,10)) << endl;

Пример класса шаблона Matrix представлен как

template <typename OutType>
class Matrix
{
    private:
        int Rows_;          //number of Rows
        int Columns_;       //number of Columns
        OutType *data_;     //row-major order allocation
    public:

        // --- Access operators 
        inline OutType & operator()(const int i, const int j)       { return data_[IDX2R(i,j,GetColumns())]; }
        inline OutType   operator()(const int i, const int j) const { return data_[IDX2R(i,j,GetColumns())]; }

        // --- SubExpressions - Range Range
        inline Expr<SubMatrixExpr<const OutType*,OutType>,OutType> operator()(Range range1, Range range2)
        {   typedef SubMatrixExpr<const OutType*,OutType> SExpr; 
                return Expr<SExpr,OutType>(SExpr(data_,Rows_,Columns_,range1.numelements_,range2.numelements_,range1.start_,range1.step_,range2.start_,range2.step_),
                        range1.numelements_,range2.numelements_); 
        }
}

Теперь я хотел бы включить назначения, подобные Matlab, как

A(Range(3,5),Range(0,10))=B;

где B - соответствующая матрица.

Я думаю, что для достижения синтаксиса, подобного Matlab, выше, две возможности были бы

  1. перегрузка оператора (), чтобы он возвращал массив указателей, а затем перегрузка оператора =, чтобы последний мог действовать между массивом указателей и Matrix;
  2. использовать уже выполненную перегрузку указанного выше оператора () и перегрузить оператор =, чтобы последний мог действовать между выражением и Matrix.

Возможно, первый вариант не очень удобен, особенно для очень больших матриц. Я прав? Существуют ли другие более эффективные возможности с использованием, возможно, более сложных функций C ++ (например, семантики перемещения)?

Большое спасибо за Вашу помощь.


person Vitality    schedule 09.05.2013    source источник


Ответы (1)


Я думаю, что лучше всего иметь неконстантную версию operator()(Range, Range), возвращающую прокси-объект, который имеет перегруженный оператор присваивания, который знает, как назначать диапазон (например, обратно в исходную матрицу).

person Mark B    schedule 09.05.2013