Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с шаблоном вложенных классов + двойная перегрузка [] / 14 сообщений из 14, страница 1 из 1
06.06.2013, 10:32
    #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
06.06.2013, 10:51
    #38287926
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с шаблоном вложенных классов + двойная перегрузка []
amigo11,

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

В с++ я пейсатель с опытом в пару месяцев, если честно. Но хотелось бы разобраться.
...
Рейтинг: 0 / 0
06.06.2013, 11:10
    #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
06.06.2013, 11:31
    #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
06.06.2013, 11:56
    #38288070
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с шаблоном вложенных классов + двойная перегрузка []
amigo11,

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

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

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

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

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


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

Ещё, для начала в шаблоном коде пиши определения методов in-line, внутри определения класса.
Будет проще. А обратное все равно почти никогда не нужно на практике.
...
Рейтинг: 0 / 0
06.06.2013, 13:28
    #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
06.06.2013, 13:50
    #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
06.06.2013, 19:48
    #38288990
MasterZiv
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Проблема с шаблоном вложенных классов + двойная перегрузка []
Я перепел эту вашу полечку на нормальный язык, но не тестировал ещё.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Проблема с шаблоном вложенных классов + двойная перегрузка [] / 14 сообщений из 14, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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