Russian Qt Forum
Июня 20, 2025, 09:32 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1] 2 3 4   Вниз
  Печать  
Автор Тема: Про templat  (Прочитано 22024 раз)
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   Вверх
  Печать  
 
Перейти в:  


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