два строковых аргумента => параметры-типы шаблона
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 27.09.11 19:27
Оценка:
Я достаточно давно не держал в руках c++(писал в основном на java) и видимо мозги повернулись слегка по-другому. Так что вопрос видимо не особо интеллектуальный.

Задача:

Есть шаблон template class A<P1,P2> ...
На вход программы приходят два строковых аргумента, первый из них соответствует некому типу T1, второй соответственно T2 и мы должны получить
A<T1,T2> avar;
avar.method1();
avar.method2();
.

но не таким способом:
if (arg1=="argT1_1" && arg2=="argT2_1") {
    A<T1_1,T2_1> avar;
    avar.method1();
    avar.method2();
}
else if (arg1=="argT1_1" && arg2=="argT2_2") {
    A<T1_1,T2_2> avar;
    avar.method1();
    avar.method2();
}
else ...
.

Вариантов комбинаций P1 и P2 достаточно много (около 100 и это не предел видимо).

Как бы получше это сделать?

------

Дополнительный вопрос:
правильно я понимаю что export template помер не успев ожить? Так что эта статья актуальна(если конкретно для gcc) и других вариантов кроме "модели включения" и "модели явного воплощения" нет: http://rsdn.ru/article/cpp/templmod.xml
Автор(ы): Валерий Лаптев
Дата: 30.10.2004
В этой статье рассказывается о методах отделения реализации шаблона от его интерфейсной части и о том, как можно заставить это работать на популярных компиляторах наподобие MS Visual C++.
?
Re: два строковых аргумента => параметры-типы шаблона
От: Vamp Россия  
Дата: 27.09.11 19:37
Оценка: +1
K>На вход программы приходят два строковых аргумента, первый из них соответствует некому типу T1, второй соответственно T2 и мы должны получить
Я, если честно, не вижу решения принципиально. Типы для шаблонов должны быть известны на этапе компиляции, и значит, сопоставить их аргументам никаким образом, кроме как через хардкод не получится. Можно if, можно switch, можно goto.

А вообще задача выглядит дико до невозможности. Нафига ТИПЫ шаблонов выносить в аргументы командной строки? Они должны задавать ПОВЕДЕНИЕ программы, а не особенности ее внутренних типов.
Да здравствует мыло душистое и веревка пушистая.
Re[2]: два строковых аргумента => параметры-типы шаблона
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 27.09.11 20:22
Оценка:
Здравствуйте, Vamp, Вы писали:

K>>На вход программы приходят два строковых аргумента, первый из них соответствует некому типу T1, второй соответственно T2 и мы должны получить

V>Я, если честно, не вижу решения принципиально. Типы для шаблонов должны быть известны на этапе компиляции, и значит, сопоставить их аргументам никаким образом, кроме как через хардкод не получится. Можно if, можно switch, можно goto.

Ну я надеялся на какое-нибудь колдунство чтобы без if/switch для каждой комбинации обойтись.

V>А вообще задача выглядит дико до невозможности. Нафига ТИПЫ шаблонов выносить в аргументы командной строки? Они должны задавать ПОВЕДЕНИЕ программы, а не особенности ее внутренних типов.


Два аргумента командной строки это не вдаваясь в детали "некий алгоритм некоего множества алгоритмов" и "режим его работы". И есть уже внешняя либа с этими самыми алгоритмами и их режимами(это я упрощаю, вообще там жуткая иерархия) которую менять нельзя и которая написана своеобразно мягко говоря. Ну то есть там явная ошибка в дизайне которую лечили костылями очень долго, и получилось что получилось. И вот вполне успешно борясь с этим своеобразием я упёрся в такую вот некрасивую задачу. Бороться по-другому можно но с использованием RTTI(не вариант в моём случае) и с чуть меньшим if/switch блоком уже от одного аргумента.
Re: два строковых аргумента => параметры-типы шаблона
От: uzhas Ниоткуда  
Дата: 28.09.11 07:11
Оценка:
Здравствуйте, kinoman, Вы писали:

один из вариантов:

{
    A avar(arg1, arg2);
    avar.method1();
    avar.method2();
}


смотрите, как просто
K>Дополнительный вопрос:
K>правильно я понимаю что export template помер не успев ожить? Так что эта статья актуальна(если конкретно для gcc) и других вариантов кроме "модели включения" и "модели явного воплощения" нет: http://rsdn.ru/article/cpp/templmod.xml
Автор(ы): Валерий Лаптев
Дата: 30.10.2004
В этой статье рассказывается о методах отделения реализации шаблона от его интерфейсной части и о том, как можно заставить это работать на популярных компиляторах наподобие MS Visual C++.
?

помер, модели какие знаете, такие и применяйте
Re[2]: два строковых аргумента => параметры-типы шаблона
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 28.09.11 09:46
Оценка: +1
Здравствуйте, uzhas, Вы писали:

U>Здравствуйте, kinoman, Вы писали:


U>один из вариантов:


U>
U>{
U>    A avar(arg1, arg2);
U>    avar.method1();
U>    avar.method2();
U>}
U>


U>смотрите, как просто


Угу, просто. Пройтись if-ом по arg1 мы получим T1_1, затем также T2_1 и создадим объекты этих классов (суммарно if-оф на порядок меньше чем для комбинации шаблона). Если это не тролинг, объяню почему такого нет а есть шаблон. Проблема в том, что в той либе которую мы не можем трогать в каждом TX_Y через typedef определёны типы ZZ1 и ZZ2 (только не спрашивай зачем — оно просто так есть) и объекты этих типов нам тоже нужны, но их конструкторы вызываются с параметрами в зависимости от параметров методов класса A, т.е. на самом деле есть не avar.method1(); а avar.method1(i1,i2,i3);. Т.е. сейчас всё примерно так:

//main.cpp
...
if (arg1=="argT1_1" && arg2=="argT2_1") {
    A<T1_1,T2_1> avar;
    avar.method1(i1,i2,i3);
    avar.method2(j1,j2);
}
...

// adef.h
template <class T1, class T2> void A<T1,T2>::method1(int i1, int i2, int i3) {
    typename T1::ZZ1 zz1(i1,i2);
    typename T2::ZZ2 zz2(zz1,i3);

    ...
}


Вобщем избавиться от этой конструкции без RTTI или правки той либы на мой взгляд невозможно. Отсюда и возникла исходная задача.
Re[3]: два строковых аргумента => параметры-типы шаблона
От: Erop Россия  
Дата: 29.09.11 06:47
Оценка:
Здравствуйте, kinoman, Вы писали:



K> т.е. на самом деле есть не avar.method1(); а avar.method1(i1,i2,i3);. Т.е. сейчас всё примерно так:


K>
K>//main.cpp
K>...
K>if (arg1=="argT1_1" && arg2=="argT2_1") {
K>    A<T1_1,T2_1> avar;
K>    avar.method1(i1,i2,i3);
K>    avar.method2(j1,j2);
K>}
K>...

K>// adef.h
K>template <class T1, class T2> void A<T1,T2>::method1(int i1, int i2, int i3) {
K>    typename T1::ZZ1 zz1(i1,i2);
K>    typename T2::ZZ2 zz2(zz1,i3);

K>    ...
K>}

K>

Совсем запутал.
А как узнать, какие ппрамниры в каком случае пнредавать?
Один из путей решения такой проблемы — сделать код полиморфным.
Типа написать какую-то структуру из котооой легео извлечь нужные ппрамнтры и полиморфную иерархию шаблонных классов, которые заворачивают всё это дело.

После этого пишешь шаблон класса-регистратора, который устанавливает ооображение строчек на типы.

Ну и получаешь прстую функцию, которая по строчке гннерит то, что надо...
Геннришь левый и правый аргумент, акод их сочетающий, пишешь полиморфно...




K>Вобщем избавиться от этой конструкции без RTTI или правки той либы на мой взгляд невозможно. Отсюда и возникла исходная задача.


Мне кажется, что если ты расскажешь чуть блльше, то легчебудет объяснтьь кто что думпнт по поводу твоего вопооса.
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[4]: два строковых аргумента => параметры-типы шаблона
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 29.09.11 09:34
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, kinoman, Вы писали:




K>> т.е. на самом деле есть не avar.method1(); а avar.method1(i1,i2,i3);. Т.е. сейчас всё примерно так:


K>>
K>>//main.cpp
K>>...
K>>if (arg1=="argT1_1" && arg2=="argT2_1") {
K>>    A<T1_1,T2_1> avar;
K>>    avar.method1(i1,i2,i3);
K>>    avar.method2(j1,j2);
K>>}
K>>...

K>>// adef.h
K>>template <class T1, class T2> void A<T1,T2>::method1(int i1, int i2, int i3) {
K>>    typename T1::ZZ1 zz1(i1,i2);
K>>    typename T2::ZZ2 zz2(zz1,i3);

K>>    ...
K>>}

K>>

E>Совсем запутал.
E>А как узнать, какие ппрамниры в каком случае пнредавать?

Если речь про i1,i2,i3,j1,j2 , то с ними проблем нет — независимо от arg1 и arg2 они передаются как показано выше (просто не показано откуда они берутся).

E>Один из путей решения такой проблемы — сделать код полиморфным.

E>Типа написать какую-то структуру из котооой легео извлечь нужные ппрамнтры и полиморфную иерархию шаблонных классов, которые заворачивают всё это дело.

E>После этого пишешь шаблон класса-регистратора, который устанавливает ооображение строчек на типы.


E>Ну и получаешь прстую функцию, которая по строчке гннерит то, что надо...

E>Геннришь левый и правый аргумент, акод их сочетающий, пишешь полиморфно...

Как я писал — я давно уже не держал в руках C++, и выражение "полиморфную иерархию шаблонных классов" вскипятило мне мозг. Если не сложно можно микропример? Я кажется понял что имеется в виду но не уверен.

K>>Вобщем избавиться от этой конструкции без RTTI или правки той либы на мой взгляд невозможно. Отсюда и возникла исходная задача.


E>Мне кажется, что если ты расскажешь чуть блльше, то легчебудет объяснтьь кто что думпнт по поводу твоего вопооса.


Да я собственно уже рассказал вроде вполне подробно в последнем примере. Больше добавить по сути нечего. Просто ещё раз уточню — в моём коде шаблон A<T1,T2> мы можем править/заменять на что-то другое, но типы-параметры этого шаблона(T1_1,...T1_X,T2_1,...,T2_X) для нас неприкасаемы (в том плане что те классы мы править не можем).

Вобщем на данный момент я прощупываю вариант решения с кодогенерацией и boost::mpl. Почти есть уверенность что сработает, но гложут сомнения что спустя полгода даже я смогу за час вспомнить/понять как это работает.
Re[5]: два строковых аргумента => параметры-типы шаблона
От: Erop Россия  
Дата: 29.09.11 12:04
Оценка: 2 (1)
Здравствуйте, kinoman, Вы писали:

K>Да я собственно уже рассказал вроде вполне подробно в последнем примере. Больше добавить по сути нечего. Просто ещё раз уточню — в моём коде шаблон A<T1,T2> мы можем править/заменять на что-то другое, но типы-параметры этого шаблона(T1_1,...T1_X,T2_1,...,T2_X) для нас неприкасаемы (в том плане что те классы мы править не можем).


Мне кажется,что я понял тебя неверно.
Но идеятакая, что типа пишешь базу абстрактную, которая умепт вызывать первый иетод через виртуальный метод, потом пишншь шаблоного наследника, который всёумеет строить и потом кмент всё вызватть из виртуальног метода того самого.
Возможно будет удобно сделать два метода. Один "сднлать это", а другой "проинициализтровать".
Потом пишнм шаблон класса,который имеет статический метод, создания нужного наследгика + метод инициализации.
А экземпляр этого инициализатора параметризуем строкой из ппрпметров командгой строки.
И, типа,нужен тебе тип ХХХ — создаёшь статический экземпляр регистратора, ппраметризованный ХХХ, от нужной строки.Он инстанцируется и регитсвой метод создания в мапе из строк в функции.

Потом ищешь в этой мапе строку,зовёшь функцию и ролучпешь объеет, реализующий нужный интнрфейс, а экземпляр ХХХ будет полем этого объекта...
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Re[6]: два строковых аргумента => параметры-типы шаблона
От: kinoman http://pseudo-tech-notes.blogspot.com/
Дата: 30.09.11 09:42
Оценка:
Здравствуйте, Erop, Вы писали:

E>Здравствуйте, kinoman, Вы писали:


K>>Да я собственно уже рассказал вроде вполне подробно в последнем примере. Больше добавить по сути нечего. Просто ещё раз уточню — в моём коде шаблон A<T1,T2> мы можем править/заменять на что-то другое, но типы-параметры этого шаблона(T1_1,...T1_X,T2_1,...,T2_X) для нас неприкасаемы (в том плане что те классы мы править не можем).


E>Мне кажется,что я понял тебя неверно.

E>Но идеятакая, что типа пишешь базу абстрактную, которая умепт вызывать первый иетод через виртуальный метод, потом пишншь шаблоного наследника, который всёумеет строить и потом кмент всё вызватть из виртуальног метода того самого.
E>Возможно будет удобно сделать два метода. Один "сднлать это", а другой "проинициализтровать".
E>Потом пишнм шаблон класса,который имеет статический метод, создания нужного наследгика + метод инициализации.
E>А экземпляр этого инициализатора параметризуем строкой из ппрпметров командгой строки.
E>И, типа,нужен тебе тип ХХХ — создаёшь статический экземпляр регистратора, ппраметризованный ХХХ, от нужной строки.Он инстанцируется и регитсвой метод создания в мапе из строк в функции.

E>Потом ищешь в этой мапе строку,зовёшь функцию и ролучпешь объеет, реализующий нужный интнрфейс, а экземпляр ХХХ будет полем этого объекта...


Угу понял. Да примерно так и сделаю. Обойдусь только кодогенерацией макросом (ну не писать же несколько сотен строк руками для создания нужного наследника в зависимости от двух строковых параметров), без boost::mpl (и слава богу ).
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.