powered by simpleCommunicator - 2.0.59     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с шаблоном вложенных классов + двойная перегрузка []
14 сообщений из 14, страница 1 из 1
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38287886
amigo11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Всем здравствуйте!

Дано:
Есть найденный в сети и вроде бы работающий класс с двойной перегрузкой квадратной скобки. Т.е. к экземпляру этого класса можно обращаться как двумерному массиву, всё красиво.
работающий класс двумерного массива для intarray.h :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
class int_array
{
    class row
    {
        friend class int_array;
        int *first_cell_in_row;
        row( int *p ) : first_cell_in_row(p) {}
    public:
        int &operator[] ( int index );
    };
    int nrows;
    int ncols;
    int *the_array;
public:
    virtual
    ~int_array( void );
    int_array( int rows, int cols );
    row operator[] (int index);
};
 
int_array::int_array( int rows, int cols ) 
: nrows ( rows ), ncols ( cols ), the_array ( new int[rows * cols])
{}
 
int_array::~int_array( void )
{
    delete [] the_array;
}
 
inline int_array::row int_array::operator[]( int index )
{
    return row( the_array + (ncols * index) );
}
 
inline int &int_array::row::operator[]( int index )
{
    return first_cell_in_row[ index ];
}

main.cpp :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#include <iostream>
#include "array.h"

int main(){

    int_array p(10,10);
    p[3][2] = 7;
    std::cout << p[3][2] << std::endl;

    return 0;
}

Требуется:
И я пытаюсь сделать этот класс шаблонным, но не получается, не понимаю, что тут не не нравится компилятору (использую mingw + codeblocks под виндой).
Было бы интересно сделать универсальный класс двумерного (в перспективе - и более высокой размерности) массива для разных типов данных.

собственно, мой некомпилирующийся код
array.h :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
template <class QType> class tst_array
{
    template <class PType> class row
    {
        friend class tst_array<PType>;
        PType *first_cell_in_row;
        row<PType>( int *p ) : first_cell_in_row(p) {}
    public:
        PType &operator[] ( int index );
    };
    int nrows;
    int ncols;
    QType *the_array;
public:
    virtual
    ~tst_array( void );
    tst_array( int rows, int cols );
    row<QType> operator[] (int index);
};

template <class QType> tst_array<QType>::tst_array( int rows, int cols ) : nrows ( rows ), ncols ( cols ), the_array ( new int[rows * cols])
{}

template <class QType> tst_array<QType>::~tst_array( void )
{
    delete [] the_array;
}

template <class QType> inline tst_array<QType>::row<QType> tst_array<QType>::operator[]( int index )
{
    return row<QType>( the_array + (ncols * index) );
}

template <class QType> inline QType &tst_array<QType>::row<QType>::operator[]( int index ) // Тут ошибка! :(
{
    return first_cell_in_row[ index ];
}

main.cpp :
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
#include <iostream>
#include "array.h"

int main(){

    tst_array<int> p(10,10);
    p[3][2] = 7;
    std::cout << p[3][2] << std::endl;

    return 0;
}

ругань компилятораerror: specializing member 'tst_array<QType>::row<QType>::operator[]' requires 'template<>' syntax
Гугление по "requires template<> syntax" ни на что внятное меня не натолкнуло, логически мой код вроде бы корректен, потому спрашиваю тут.
Подскажите, в чём же тут ошибка и как это можно обойти или исправить.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38287926
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

А зачем вам шаблон для вложенного класса?
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38287961
amigo11
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Anatoly Moskovsky,
мне кажется это нужно, т.к. вложенный класс row, так же как и tst_array должен уметь работать с разными типами данных.
Но просто так засунуть QType в row у меня не получилось, пришлось писать template <class PType>.

В с++ я пейсатель с опытом в пару месяцев, если честно. Но хотелось бы разобраться.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38287967
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ты нашел какой-то многословный варинт. предлагаю замену
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
template<typename T>
class Matrix
{
    size_t nrows;
    size_t ncols;
    T *the_array;
public:
    Matrix( size_t rows, size_t cols )  : nrows ( rows ), ncols ( cols ), the_array ( new T[rows * cols])
    {
    }
    ~Matrix( ) {
        delete [] the_array;
    }
    T* operator[] (size_t row) {
        return the_array + ncols * row;
    }
    const T* operator[] (size_t row) const {
        return the_array + ncols * row;
    }
private:
    Matrix(const Matrix&);
    Matrix& operator=(const Matrix&);
};
...
Matrix<int> m(10, 20);
m[0][1] = 10;
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288017
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

Если решаете практическую задачу то лучше применить vector<vector<int> > или list<vector<int> >, или готовые классы матриц в зависимости от ситуации и требуемых операций и требований к ним, (чтобы самому написать хороший такой класс уйдут годы я думаю). Если хотите сделать вложенный шаблонный класс с независимой специализацией (отличный от внешнего класса тип) то для всех определений функций-членов вложенного класса нужно писать:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
...

template <class QType> // Свой для каждого шаблонного класса
template <class PType> // Свой для каждого шаблонного класса
PType & typename tst_array<QType>::row<PType>::*

...


Если хотите просто многомерный массив фиксированного размера, можете сделать обертку над vector<T> с какой-нибудь функцией многомерной адресации элементов
Код: plaintext
1.
2.
3.
4.
5.
template <int SizeX, int SizeY, int SizeZ> class shiva
...
m_v.resize(SizeX * SizeY * SizeZ);
...
T & at(int x, int y, int z) throw(std::out_of_range) { return m_v.at(SizeZ * z + SizeY * y + x); }
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288070
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

Исходный класс не такой уж и хороший, нет например константного доступа.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288082
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

Начнем с того, что у шаблона должен быть один параметр шаблона, а не два.
Вложенный класс строки будет с тем же параметром шаблона, что и внешний.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288093
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

Деструктор вряд ли должен быть виртуальным, это заведомо неполиморфный класс.

Впрочем, Анатолий вроде бы уже дал вам хороший пример кода, лучше изучить его.з
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288107
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широков,

Наверное для целей лучшего контроля доступа к элементам, например, проверки выхода за границы матрицы, тот вариант со вложенным классом строки более прогрессивен.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288122
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
[quot amigo11]Anatoly Moskovsky,
мне кажется это нужно, т.к. вложенный класс row, так же как и tst_array должен уметь работать с разными типами данных.


В том то и дело, что тип данных у них одинаков. Он может быть любым, но он один и тот же у главного и вложенного классов, более того, если он будет разным, это будет ошибка.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288131
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
amigo11,

Ещё, для начала в шаблоном коде пиши определения методов in-line, внутри определения класса.
Будет проще. А обратное все равно почти никогда не нужно на практике.
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288263
Фотография Анатолий Широков
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
sherzod_,

Код: plaintext
1.
T & at(int x, int y, int z) throw(std::out_of_range) { return m_v.at(SizeZ * z + SizeY * y + x); }



ну, с твоего позволения поправлю твою функцию вычисления смещения элемента при линейной развертке:

Код: plaintext
1.
T & at(int x, int y, int z) throw(std::out_of_range) { return m_v.at(SizeY*SizeZ * x + SizeZ * y + z); }
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288314
sherzod_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Анатолий Широковsherzod_,
Код: plaintext
1.
T & at(int x, int y, int z) throw(std::out_of_range) { return m_v.at(SizeZ * z + SizeY * y + x); }


ну, с твоего позволения поправлю твою функцию вычисления смещения элемента при линейной развертке:
Код: plaintext
1.
T & at(int x, int y, int z) throw(std::out_of_range) { return m_v.at(SizeY*SizeZ * x + SizeZ * y + z); }

Конечно, виноват, недовспомнил недодумал. Тогда уже если смотреть как на декартову СК фронтально, с глубиной, получается SizeX * SizeY * z + SizeX * y + x :).
...
Рейтинг: 0 / 0
Проблема с шаблоном вложенных классов + двойная перегрузка []
    #38288990
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я перепел эту вашу полечку на нормальный язык, но не тестировал ещё.
...
Рейтинг: 0 / 0
14 сообщений из 14, страница 1 из 1
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с шаблоном вложенных классов + двойная перегрузка []
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]