crossplatform.ru

Здравствуйте, гость ( Вход | Регистрация )

4 страниц V   1 2 3 > »   
Ответить в данную темуНачать новую тему
> Шаблон, динамическое значения параметра шаблона, параметр не является типом
ViGOur
  опции профиля:
сообщение 15.2.2013, 8:58
Сообщение #1


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Я создаю динамически объекты некоторых произвольных классов, родитель у них один, тип только разный.
Для вопроизведения ошибки набросал следующий код:
class CEnumClass
{
public:
    enum eEnum{
        P1,
        P2,
        P3
    };
};

template <class T, int TYPE>
class CClass
{
// ...
};

int main(int argc, char *argv[])
{
    CEnumClass::eEnum tmpEnum = CEnumClass::P1;
    const int n0 = 10;
    const int n1 = tmpEnum;

    CClass<int, 0> mc0;                // OK
    CClass<int, n0> mc1;              // OK
    CClass<int, CEnumClass::P1> mc2; // OK
    //CClass<int, n1> mc3;            // error: 'n1' cannot appear in a constant-expression
    //CClass<int, tmpEnum> mc4;  // error: 'tmpEnum' cannot appear in a constant-expression
}

В конструкции template <class T, int TYPE>, TYPE сделан для того, чтобы при инстанцировании различались типы объектов данного класса с задумкой на будущее... И данный тип передается динамически, во время выполнения программы. Тоесть, у меня из вне приходит некий tmpEnum, что в примере и я на основе него должен создать-получить объект mc4, но возникает ошибка указанная в коментарии при создании объекта mc4 .

Как я понимаю это из-за того, что у меня переменная создается динамически (во время выполнения), а шаблон должен быть инстанцирован статически (во время компиляции). Поправьте меня если я ошибаюсь.


И собственно вопрос, как сделать так, чтобы это работало и возможно ли это? :)
Если это не возможно, то буду думать как сделать по другому...
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ssoft
  опции профиля:
сообщение 15.2.2013, 9:37
Сообщение #2


Участник
**

Группа: Участник
Сообщений: 130
Регистрация: 17.2.2010
Из: Москва
Пользователь №: 1470

Спасибо сказали: 30 раз(а)




Репутация:   3  


Цитата(ViGOur @ 15.2.2013, 9:58) *
Как я понимаю это из-за того, что у меня переменная создается динамически (во время выполнения), а шаблон должен быть инстанцирован статически (во время компиляции). Поправьте меня если я ошибаюсь.

И собственно вопрос, как сделать так, чтобы это работало и возможно ли это? :)
Если это не возможно, то буду думать как сделать по другому...


Имено так, шаблоны конкретизируются во время компиляции и нет возможности использовать динамически изменяющиеся параметры шаблона.
В данном случае, я подозреваю, что необходимо использовать паттерн "Фабрика".
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.2.2013, 10:19
Сообщение #3


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Боюсь паттерн Фабричный метод здесь не поможет, дело в том, что шаблонный класс реализован как синглтон, которому в качестве параметров передаются:
1. класс, объект которого нужно создать-получить.
2. некий внутренний тип, который явно идентифицирует объект, так как класс для некоего множества объектов может быть один, а тип у них разный...

Например:
class CAnimal{};
class CCat: CAnimal{};
class CDog: CAnimal{};

CAnimal *p1 = CSingleton<CCat, eMurka>::init
...
CAnimal *p2 = CSingleton<CDog, eVolk>::init();
CAnimal *p3 = CSingleton<CDog, ePudel>::init();
CAnimal *p4 = CSingleton<CDog, eTaksa>::init();
Пока вижу только не очень хороший выход в использовании ручной типизации, но это геморно и чревато ошибками... :(

Или я что-то не додумываю-недопонию?
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Iron Bug
  опции профиля:
сообщение 15.2.2013, 10:26
Сообщение #4


Профессионал
*****

Группа: Модератор
Сообщений: 1611
Регистрация: 6.2.2009
Из: Yekaterinburg
Пользователь №: 533

Спасибо сказали: 219 раз(а)




Репутация:   12  


если это связано с типами, то тожно тупо в конструкторе передавать std::type_info. ну или вообще что угодно.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.2.2013, 10:39
Сообщение #5


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Неа, в моем случае объекты p3 и p4 (ePudel и eTaksa) это разные типы, и так как они по разному инстанцируются, то и разные объекты.
Простая передача параметра в конструкторе не даст того же результата...

Например,
CAnimal *p3 = CSingleton<CDog, ePudel>::init();
CAnimal *p4 = CSingleton<CDog, eTaksa>::init();
CAnimal *p5 = CSingleton<CDog, ePudel>::init();
CAnimal *p6 = CSingleton<CDog, eTaksa>::init();
p5 == p3, а p6 == p4, но p5 != p6.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.2.2013, 11:20
Сообщение #6


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


имхо, виртуальное наследование спасёт )

class CDog
{
protected:
    virtual init()=0;
};


class CPudel:CDog
{
   init()
   {
   }
};

...

Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.2.2013, 11:33
Сообщение #7


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Цитата(Алексей1153 @ 15.2.2013, 12:20) *
имхо, виртуальное наследование спасёт )
Это как я понимаю и есть фабричный метод!
Цитата(ViGOur @ 15.2.2013, 11:19) *
Боюсь паттерн Фабричный метод здесь не поможет, дело в том, что шаблонный класс реализован как синглтон, которому в качестве параметров передаются:
И если это реализовывать, то в моем случае класс CPudel, будет заботится о создании самого себя, в место шаблонного класса (который, как я писал уже выше, является синглтоном), а вместе с этим в нем нужно будет закрывать: конструктор, деструктор, конструктор копирования и оператор присваивания... А так же, если в моем зоопарке будет за 100500 зверей, то всем им нужно будет делать то же самое и описывать своё рождение!

Как-то не комильфо...

Звери тут в качестве примера и не более! :)

з.ы. или я все же не правильно понял идею вашей реализации.
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.2.2013, 11:45
Сообщение #8


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


Цитата(ViGOur @ 15.2.2013, 14:33) *
Это как я понимаю и есть фабричный метод!

нет, это возможности языка. Фабрика - это отдельный класс/процедура, которая порождает объекты по маркеру их типа и возвращает указатель типа "родитель"

синглтон можно сделать статическим методом родительского класса (синглтон Майерса)

а описывать разницу в поведении типов всё равно где-то придётся :)

можно все классы поместить в один namespace , тогда путаться ничего не будет
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
ViGOur
  опции профиля:
сообщение 15.2.2013, 11:45
Сообщение #9


Мастер
******

Группа: Модератор
Сообщений: 3296
Регистрация: 9.10.2007
Из: Москва
Пользователь №: 4

Спасибо сказали: 231 раз(а)




Репутация:   40  


Пока я вижу выход, как я уже говорил:
Цитата(ViGOur @ 15.2.2013, 11:19) *
Пока вижу только не очень хороший выход в использовании ручной типизации, но это геморно и чревато ошибками... :(
в использовании switch, например так:
switch(type)
{
case P1: CClass<int, CEnumClass::P1> mc1;break;
case P2: CClass<int, CEnumClass::P2> mc2;break;
case P3: CClass<int, CEnumClass::P3> mc3;break;
}
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение
Алексей1153
  опции профиля:
сообщение 15.2.2013, 11:47
Сообщение #10


фрилансер
******

Группа: Участник
Сообщений: 2939
Регистрация: 19.6.2010
Из: Обливион
Пользователь №: 1822

Спасибо сказали: 215 раз(а)




Репутация:   34  


и ещё - при отладке с шаблонами можно запариться, так как отладчик не сможет показать, какой именно сейчас тип у владельца процедуры

Цитата(ViGOur @ 15.2.2013, 14:45) *
в использовании switch,

этот код и будет находится в методе-фабрике

Сообщение отредактировал Алексей1153 - 15.2.2013, 11:47
Перейти в начало страницы
 
Быстрая цитата+Цитировать сообщение

4 страниц V   1 2 3 > » 
Быстрый ответОтветить в данную темуНачать новую тему
Теги
Нет тегов для показа


1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0




RSS Текстовая версия Сейчас: 20.4.2024, 13:13