Модераторы: Daevaorn

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> [C++] Инициализация класса матрицы, двумерным массивом 
V
    Опции темы
JackYF
  Дата 29.11.2007, 18:45 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Итак, реализуется свой велосипедный класс "матрица" для сдачи лабы.

Вопрос в следующем: я хочу, чтобы матрица умела инициализироваться двумерным заданным массивом наподобие:
Код

int m[2][3] = { {1, 2, 3}, {4, 5, 6} };


Класс шаблонный, единственный параметр шаблона - тип.
Конструктор
Код

standart_matrix(T** values, size_t rows, size_t columns);


справедливо не срабатывает, так как int[2][3] не приводится к int**, у него другая физ. структура.

Возможные видимые мной выходы: 

1. cделать конструктор
Код

standart_matrix(void* values, size_t rows, size_t columns);

К нему обращаться через
Код

//...
standart_matrix matrix(reinterpret_cast<void*>(m), 2, 3);


2.  Сделать конструктор шаблонным, типа
Код

template <size_t columns>
standart_matrix(T values[][columns], size_t rows);


Первый вариант - не очень красиво и потенциально опасно, второй вариант - может быть сгенерировано многовато функций для каждой из используемых в клиентском коде матриц, по одной для каждого числа столбцов.

Кто какой вариант предпочёл бы? Или предложите свой.

Это сообщение отредактировал(а) JackYF - 29.11.2007, 19:33


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 29.11.2007, 19:24 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  29.11.2007,  18:45 Найти цитируемый пост)
Вопрос в следующем: я хочу, чтобы матрица умела инициализироваться двумерным заданным массивом наподобие:

Жди С++09 - возможно туда включат initializer lists smile.


Цитата(JackYF @  29.11.2007,  18:45 Найти цитируемый пост)
int m[2][3] = { {1, 2, 3}, {4, 5, 6} };

Давай, для начала, разберёмся с этим: ты хочешь параметры конструктора size_t rows и size_t columns передавать таким образом(через "квадратные скобочки")?

Можешь написать как ты хочешь, чтобы выглядела инициализация(примерно, но без таких ляпов)?


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 29.11.2007, 19:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  29.11.2007,  19:24 Найти цитируемый пост)
Давай, для начала, разберёмся с этим: ты хочешь параметры конструктора size_t rows и size_t columns передавать таким образом(через "квадратные скобочки")?

Можешь написать как ты хочешь, чтобы выглядела инициализация(примерно, но без таких ляпов)?

Эээ... не понял, объясни, в чём ляп.

Ну, в идеальном случае так:
Код

standart_matrix matrix(m, 2, 3);
// вместо 2,3 здесь можно подставить sizeof(...)/sizeof(...) и т.д...


Добавлено через 2 минуты и 38 секунд
Цитата(archimed7592 @  29.11.2007,  19:24 Найти цитируемый пост)
Жди С++09 - возможно туда включат initializer lists

Жду. Только вот лабу через 2 недели сдавать smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 29.11.2007, 19:50 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Цитата(JackYF @  29.11.2007,  19:32 Найти цитируемый пост)
Эээ... не понял, объясни, в чём ляп.


Цитата(JackYF @  29.11.2007,  18:45 Найти цитируемый пост)
Вопрос в следующем: я хочу, чтобы матрица умела инициализироваться двумерным заданным массивом наподобие:


Цитата(JackYF @  29.11.2007,  18:45 Найти цитируемый пост)
int m[2][3]

Видишь ли, в языке С++ так массивы делают smile. Т.е. это будет как минимум массив матриц...


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 29.11.2007, 20:07 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  29.11.2007,  19:50 Найти цитируемый пост)
Т.е. это будет как минимум массив матриц... 


archimed7592, ты чего?
у меня два измерения - строки, столбцы. Где массив матриц-то?


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 29.11.2007, 20:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



Ытить... Посыпаю голову пеплом. Спать уже пора smile.


Цитата(JackYF @  29.11.2007,  18:45 Найти цитируемый пост)
Кто какой вариант предпочёл бы?

Второй.
Во-первых, с вероятностью 80% эти ф-ции заинлайнятся. Особенно, если весь конструктор будет представлять из себя forwarder на какой-нибудь.
Во-вторых, даже если бинарник разрастётся, то ты этого не заметишь(ну что такое на сегодняшний день 100 кб?) smile.
В-третьих - это лаба smile.

Это сообщение отредактировал(а) archimed7592 - 29.11.2007, 20:30


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
JackYF
Дата 29.11.2007, 20:32 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(archimed7592 @  29.11.2007,  20:25 Найти цитируемый пост)
Особенно, если весь конструктор будет представлять из себя forwarder на какой-нибудь.

Да, так и есть.

Что ж, позиция ясна. Со всем согласен, поэтому пока остановлюсь тоже на варианте 2, как рабочем.
Тему пока не закрываю, может, ещё кто высказаться захочет.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
archimed7592
Дата 29.11.2007, 20:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Архимед
****


Профиль
Группа: Завсегдатай
Сообщений: 2531
Регистрация: 12.6.2004
Где: Moscow

Репутация: 58
Всего: 93



За первый вариант вряд ли кто выскажется smile.
smile


--------------------
If you have an apple and I have an apple and we exchange apples then you and I will still each have one apple. But if you have an idea and I have an idea and we exchange these ideas, then each of us will have two ideas.
© George Bernard Shaw
PM Jabber   Вверх
bsa
Дата 29.11.2007, 21:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



или я что-то не понял, или у меня крутой компилятор:
Код
#include <iostream>
template<typename T>
class Matrix
{
public:
        template<int m, int n>
        Matrix(const T (&values)[m][n]){
                std::cout << m << "," << n << std::endl;
                for(int i = 0; i < m; ++i) {
                        for(int j = 0; j < n; ++j)
                                std::cout << values[i][j] << " ";
                        std::cout << std::endl;
                }
        }
};

int main()
{
        int x[2][3] = { {1, 2, 3}, {4, 5, 6} };
        Matrix<int> t(x);
        return 0;
}


Это сообщение отредактировал(а) bsa - 29.11.2007, 21:53
PM   Вверх
JackYF
Дата 29.11.2007, 22:12 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Цитата(bsa @  29.11.2007,  21:51 Найти цитируемый пост)
template<int m, int n>
        Matrix(const T (&values)[m][n]){

Правильно. Это развитие второго варианта, шаблонный конструктор. Только уже с двумя параметрами smile


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
JackYF
Дата 29.11.2007, 22:55 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



Так. Теперь меня удивляет компилятор... g++ 4.2.1

Здесь идут части одного .hpp-файла, который инклюдится в один .cpp
Сначала часть-"заголовок":
Код

template < typename T >                                                                                                                              
        class standart_matrix                                                                                                                                
        {                                                                                                                                                    
         private:                                                                                                                                            
            typedef standart_matrix<T> self;                                                                                                                 
                                                                                                                                                             
            size_t __rows;                                                                                                                                   
            size_t __columns;                                                                                                                                
             T* __storage;                                                                                                                                    
                                                                                                                                                             
         protected:                                                                                                                                          
            ulong _smp_to_storage_pos(const matrix_position& smp) const;                                                                                     
            void _verify_sizes(const self& other) const;                                                                                                     
                                                                                                                                                             
            void _ctor(size_t rows, size_t columns);                                                                                                         
            void _ctor(const self& other);                                                                                                                   
            void _dtor();                                                                                                                                    
         public:                                                                                                                                             
            typedef matrix_position smp;                                                                                                                     
            typedef size_t size_type;                                                                                                                        
                                                                                                                                                             
            standart_matrix(size_t rows, size_t columns);                                                                                                    
            template < size_t rows, size_t columns >                                                                                                         
            standart_matrix(const T (&values)[rows][columns]);                                                                                               
            standart_matrix(const self& other);                                                                                                              
            self& operator=(const self& other);                                                                                                              
                                                                                                                                                             
            template < size_t rows, size_t columns >                                                                                                         
            void assign(const T (&values)[rows][columns]);                                                                                                   
                                                                                                                                                             
            T& operator[](const smp& index );                                                                                                                
            const T& operator[](const smp& index) const;                                                                                                     
            void set(const smp& index, const T& value);                                                                                                      
            const T& get(const smp& index) const;                                                                                                            
                                                                                                                                                             
            standart_matrix<T>& operator+=(const standart_matrix<T>& other);                                                                                 
            standart_matrix<T>& operator-=(const standart_matrix<T>& other);                                                                                 
            standart_matrix<T>& operator*=(const standart_matrix<T>& other);                                                                                 
                                                                                                                                                             
            const self operator-() const;
            
            size_t rows() const;                                                                                                                             
            size_t columns() const;                                                                                                                          
                                                                                                                                                             
            virtual ~standart_matrix();                                                                                                                      
                                                                                                                                                             
            const standart_matrix<T> operator+(const standart_matrix<T>& other) const;                                                                       
            const standart_matrix<T> operator-(const standart_matrix<T>& other) const;                                                                       
            const standart_matrix<T> operator*(const standart_matrix<T>& other) const;                                                                       
                                                                                                                                                             
            bool operator==(const standart_matrix<T>& other) const;                                                                                          
            bool operator!=(const standart_matrix<T>& other) const;                                                                            


Затем один из методов:
Код

template < size_t rows, size_t columns >                                                                                                             
template < typename T >                                                                                                                              
standart_matrix<T>::standart_matrix(const T (&values)[rows][columns])                                                                                
{                                                                                                                                                    
     _ctor(rows, columns);                                                                                                                            
     // тут должно быть код, но пока его нет...                                            
}  


Ругается компилятор так:
Цитата

/home/jackyf/Work/Programming/linux/yfLibrary/workcopy-linux/yf/math/standart_matrix.hpp:158: error: invalid use of incomplete type ‘class yf::math::standart_matrix<T>’
/home/jackyf/Work/Programming/linux/yfLibrary/workcopy-linux/yf/math/standart_matrix.hpp:43: error: declaration of ‘class yf::math::standart_matrix<T>’

Без этого самого метода всё чики-пики. Вопрос - почему компилятор считает, что класс неполон?  smile 

Это сообщение отредактировал(а) JackYF - 29.11.2007, 22:57


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
MAKCim
Дата 29.11.2007, 23:05 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Воін дZэна
****


Профиль
Группа: Экс. модератор
Сообщений: 5644
Регистрация: 10.12.2005
Где: Менск, РБ

Репутация: 52
Всего: 207



Код

template < class T > 
template < size_t rows, size_t columns >                                                                                                                                                                                                                             
standart_matrix<T>::standart_matrix(const T (&values)[rows][columns])                                                                                
{                                                                                                                                                    
     _ctor(rows, columns);                                                                                                                            
     // тут должно быть код, но пока его нет...                                            
}  



--------------------
Ах, у елі, ах, у ёлкі, ах, у елі злыя волкі ©

PM MAIL   Вверх
bsa
Дата 29.11.2007, 23:09 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



А если 
Код
template < size_t rows, size_t columns >
template < typename T >
заменить на:
Код
template <typename T, size_t rows, size_t columns>

PM   Вверх
JackYF
Дата 29.11.2007, 23:10 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


полуавантюрист
****


Профиль
Группа: Участник
Сообщений: 5814
Регистрация: 28.8.2004
Где: страна тысячи озё р

Репутация: 18
Всего: 162



MAKCim, да, было такое подозрение.

На это компилятор говорит, что
Цитата

/home/jackyf/Work/Programming/linux/yfLibrary/workcopy-linux/yf/math/standart_matrix.hpp:158: error: prototype for ‘yf::math::standart_matrix<T>::standart_matrix(const T (&)[rows][columns])’ does not match any in class ‘yf::math::standart_matrix<T>’

И пока не поменяешь обратно порядок template'ов, говорит о несоответствии прототипов.

Добавлено через 1 минуту и 41 секунду
bsa, аналогично с вариантом MAKCimа. На прототипы начинает ругаться.

Добавлено через 2 минуты и 38 секунд
Вариант
Код

template <size_t rows, size_t columns, typename T >

На прототипы не ругается, но выдаёт ошибку про "imcomplete type".

Добавлено через 8 минут и 18 секунд
Сужаем ошибку. За основу взял пример bsa:

Код

#include <iostream>                                                                                                                                          
template<typename T>                                                                                                                                         
class Matrix                                                                                                                                                 
{                                                                                                                                                            
    public:                                                                                                                                                  
        template<int m, int n>                                                                                                                               
        Matrix(const T (&values)[m][n]);                                                                                                                     
};                                                                                                                                                           
                                                                                                                                                             
template<int m, int n>                                                                                                                                       
template<typename T>                                                                                                                                         
Matrix<T>::Matrix(const T (&values)[m][n])                                                                                                                   
{                                                                                                                                                            
    std::cout << m << "," << n << std::endl;                                                                                                                 
    for (int i = 0; i < m; ++i)                                                                                                                              
    {                                                                                                                                                        
        for (int j = 0; j < n; ++j)                                                                                                                          
        {                                                                                                                                                    
            std::cout << values[i][j] << " ";                                                                                                                
        }                                                                                                                                                    
        std::cout << std::endl;                                                                                                                              
    }                                                                                                                                                        
}                                                                                                                                                            
                                                                                                                                                             
int main()                                                                                                                                                   
{                                                                                                                                                            
    int x[2][3] = { {1, 2, 3}, {4, 5, 6} };                                                                                                                  
    Matrix<int> t(x);                                                                                                                                        
    return 0;                                                                                                                                                
}                      

Цитата

main.cpp:12: error: invalid use of incomplete type ‘class Matrix<T>’
main.cpp:4: error: declaration of ‘class Matrix<T>’


Итого имеем то же самое.


--------------------
Пожаловаться на меня как модератора можно здесь.
PM MAIL Jabber   Вверх
bsa
Дата 29.11.2007, 23:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Эксперт
****


Профиль
Группа: Модератор
Сообщений: 9185
Регистрация: 6.4.2006
Где: Москва, Россия

Репутация: 63
Всего: 196



попробуй определить конструктор в теле класса. Если, конечно, на принцип не пошел...
PM   Вверх
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0697 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.