Russian Qt Forum
Ноябрь 24, 2024, 05:36 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Про templat  (Прочитано 20819 раз)
Ced
Гость
« : Май 06, 2017, 11:54 »

Коллеги, подскажите можно ли иметь шаблонный метод в классе, который не является template?
« Последнее редактирование: Май 06, 2017, 12:51 от Ced » Записан
ViTech
Гипер активный житель
*****
Offline Offline

Сообщений: 858



Просмотр профиля
« Ответ #1 : Май 06, 2017, 12:52 »

Можно.
Записан

Пока сам не сделаешь...
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #2 : Май 06, 2017, 13:06 »

[off]Ну вот, началось пагубное увлечение. "Коготок увяз - всей птичке пропасть"  Плачущий[/off]
Записан
Ced
Гость
« Ответ #3 : Май 06, 2017, 19:35 »

[off]Ну вот, началось пагубное увлечение. "Коготок увяз - всей птичке пропасть"  Плачущий[/off]

Я заметил. Но задача реально того требует.
Записан
Ced
Гость
« Ответ #4 : Май 06, 2017, 22:16 »

Можно.

Спасибо. Еще вопрос. Имеется вот такая конструкция
Код:
template <typename T>class X : public Y
При создании объекта класса X сперва запускается конструктор Y. Y не template.
Могу ли я определить значение Т в ходе выполнения конструктора Y?
Или может можно сделать иначе, так, чтобы сперва создать объект Y, а после выбрать значение Т?
Записан
Ced
Гость
« Ответ #5 : Май 07, 2017, 11:28 »

Что то я не пойму
Код:
template <typename T>class Parametr : public ParametrName
{
.......
    Parametr<T> ();
...........
};

Parametr<float> *x;

x = new Parametr<float>;

И в итоге:
Код:
ошибка: undefined reference to `Parametr<float>::Parametr()'

Что не так?
« Последнее редактирование: Май 07, 2017, 12:05 от Ced » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Май 07, 2017, 13:00 »

Могу ли я определить значение Т в ходе выполнения конструктора Y?
Или может можно сделать иначе, так, чтобы сперва создать объект Y, а после выбрать значение Т?
Нет. Темплаты - они как бы "статики", т.е. все известно и решается на этапе компиляции, никаких "динамических" манипуляций с типом нет.

Что то я не пойму
Код
C++ (Qt)
template <typename T>class Parametr : public ParametrName
{
.......
//    Parametr<T> ();
     Parametr();
...........
};
 
template<typename T>
Parametr<T>::Parametr( void )
{
..
}
 

Записан
Ced
Гость
« Ответ #7 : Май 07, 2017, 13:08 »


Код
C++ (Qt)
template <typename T>class Parametr : public ParametrName
{
.......
//    Parametr<T> ();
     Parametr();
...........
};
 
template<typename T>
Parametr<T>::Parametr( void )
{
..
}
 

Попробовал. Результат тот же. Компилятор не желает видеть, что у класса Parametr есть такой конструктор.
Но вообще это тестовый пример. Я все упростил от безысходности. Бьюсь, как в стенку. А задумка в целом такова:
Есть шаблонный класс. Хочу создать вектор ссылок на объекты этого класса. За тем определить длину вектора. Для каждого элемента вектора динамически создать объект. У каждого объекта свое значение параметра Т. Это возможно?
« Последнее редактирование: Май 07, 2017, 13:20 от Ced » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #8 : Май 07, 2017, 13:40 »

Попробовал. Результат тот же. Компилятор не желает видеть, что у класса Parametr есть такой конструктор.
Учтите что тело конструктора должно находиться в той же "единице трансляции"
Но вообще это тестовый пример.
Тем лучше, выкладывайте его как zip с компилируемым примером внутри
А задумка в целом такова:
Есть шаблонный класс. Хочу создать вектор ссылок на объекты этого класса. За тем определить длину вектора. Для каждого элемента вектора динамически создать объект. У каждого объекта свое значение параметра Т. Это возможно?
Да, это довольно популярная задача, только "вектор ссылок" вряд ли, наверное имелся ввиду "вектор указателей". Пишете базовый класс, от него наследуете темплейт класс (как Вы и начали делать) и работаете через виртуалы базового класса.
Записан
Ced
Гость
« Ответ #9 : Май 07, 2017, 13:49 »

Цитировать
Учтите что тело конструктора должно находиться в той же "единице трансляции"

Расположение таково:
Класс Parametr находится в файле Parametrs.h
Конструктор - в файле Parametrs.cpp
Объект *x пытаюсь создавать в файле MyServer.cpp как локальную переменную в конструкторе класса MyServer.
Все в одном проекте.
Компилятор не ругается на объявление Parametr<float> *x и стало быть класс Parametr он видит. А вот наличие в нем конструктора не желает признавать.
Я сперва пользовался другим конструктором с параметрами. Потом решил исключить все возможные причины ошибки и создал кнструктор предельно простой.
Это не помогло.

Раз задуманная мною схема реализуема,  значит с этой проблемой надо разобраться. Посоветуйте пожалуйста, в чем все же ошибка?
« Последнее редактирование: Май 07, 2017, 14:09 от Ced » Записан
Ced
Гость
« Ответ #10 : Май 07, 2017, 14:15 »

Цитировать
Учтите что тело конструктора должно находиться в той же "единице трансляции"
До меня дошло наконец. Спасибо. Это для шаблонов такая особенность?
И как же быть? Описывать конструктор непосредственно в теле класса? Или как это принято решать?
Про это где-то написано?
« Последнее редактирование: Май 07, 2017, 14:27 от Ced » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #11 : Май 07, 2017, 14:28 »

Дошло наконец. Спасибо. Это для шаблонов такая особенность?
Да, в момент "инстанциации" все тела должны быть видимы
И как же быть? Описывать конструктор непосредственно в теле класса?
Можно и так, это несколько "замусоривает" хедер, но - дело вкуса. Я обычно сваливаю тела в файл
напр "MyClass_Templates.cpp", который включаю НЕ в проект, а в хедер
Код
C++ (Qt)
// файл MyClass.h
#ifndef MYCLASS_H
#define MYCLASS_H
 
template<class T>
class MyClass {
...
};
#include "MyClass_Templates.cpp"
 
#endif  // MYCLASS_H
 

[off]
Но задача реально того требует.
Увлечение этой заразой сгубило немало хороших ребят [/off]
Записан
Ced
Гость
« Ответ #12 : Май 07, 2017, 14:35 »

Спасибо огромное. Бился с этим три дня непрерывно. Нигде не смог прочитать. С этим понятно. Помогите пожалуйста еще с вектором.

Я предполагаю объявить его так

Код:
template <typename T> class X
{

......

};

......

int n = 10;


QVector<X<typename T>> *Y = new QVector(n)

.......

Y<float>[j] = new X<float>(.....);


Это корректно?
« Последнее редактирование: Май 07, 2017, 14:43 от Ced » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #13 : Май 07, 2017, 15:47 »

Я предполагаю объявить его так

Код:
template <typename T> class X
{

......

};

......

int n = 10;


QVector<X<typename T>> *Y = new QVector(n)

.......

Y<float>[j] = new X<float>(.....);


Это корректно?
Нет.
Код
C++ (Qt)
QVector<X<typename T>> *Y = new QVector(n)
 
Это уже не объявление а инстациирование, здесь может быть только конкретный тип, напр float. но никак не typename. Правильно напр так
Код
C++ (Qt)
template <typename T>
class X : public BaseElement
{
};
 
QVector<BaseElement *> * ptrY = new QVector<BaseElement *> (n);
(*ptrY)[0] = new X<float>(..);
 
В контейнере могут быть только эл-ты одного типа, поэтому придется там хранить указатели на базовый класс, напр BaseElement.

И опять Вы допускаете ту же ошибку - обращение к массиву векторов вместо обращения к эл-ту вектора
Записан
Ced
Гость
« Ответ #14 : Май 07, 2017, 15:50 »

Спасибо. Сняли с меня огромную головную боль. Раньше никогда с шаблонами не работал. Очень помогли.
Записан
Страниц: [1] 2 3 4   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.206 секунд. Запросов: 23.