Название: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 18, 2016, 13:02 Всем привет,
понадобилась довольно простая вещь. Скажем, есть класс A, и есть шаблон типа Код: template<class A, class X> со временем выяснилось, что некоторые наследники от класса A имеют некоторые различные методы. Например, что то типа этого: Код: class B: public A В шаблоне есть несколько мест, где нужно, в зависимости от типа A, вызывать тот или иной метод наследника. Типа такого: Код: void T<A,X>::doStuff() Проблему можно решить через runtime с помощью dynamic_cast, и это будет работать 100%. Вопрос, можно ли каким-то образом это решить через специализацию шаблона? Или современный C++ все еще далек от элементарных вещей? Пробовал через Код: template<class X> что выглядит логичным с точки зрения разработчика (специализируем первый параметр шаблона классом D), но ни одна подобная конструкция не компилиццо :( Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 18, 2016, 13:52 Цитировать Вопрос, можно ли каким-то образом это решить через специализацию шаблона? Можно. И чтоб весь класс T не специализировать, достаточно завести хелпер, который будет возвращать нужный метод:Код
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 18, 2016, 15:27 Идею понял, спасибо :)
Получается, на КАЖДЫЙ метод КАЖДОГО класса, который будет параметром шаблона, создаем свой враппер-хелпер... Немножко усложним задачку... Предположим, что вызовов методов типа method...() мало. Надо в doStuff() обработать результаты их выполнения и в зависимости от этого сделать то или иное действие. Т.е. так: Код: // if this is A: Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 18, 2016, 17:28 Цитировать Получается, на КАЖДЫЙ метод КАЖДОГО класса, который будет параметром шаблона, создаем свой враппер-хелпер... Не совсем.. Хелпер может содержать ни один метод - их там может быть несколько, в зависимости от задачи. Он просто задаёт интерфейс, а реализация для конкретного класса специализируется. Идея в том, что проще написать легковесные специализации хелпера, чем специализации самого класса T. Цитировать Немножко усложним задачку... Предположим, что вызовов методов типа method...() мало. Надо в doStuff() обработать результаты их выполнения и в зависимости от этого сделать то или иное действие. И в чём проблема? Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 18, 2016, 17:37 Немножко усложним задачку... Если очевидна/налицо "динамика", то зачем делать ее "статикой"? Приведетесь dynamic_cast<>, не облезете. Предположим, что вызовов методов типа method...() мало. Надо в doStuff() обработать результаты их выполнения и в зависимости от этого сделать то или иное действие. Т.е. так: И в чём проблема? Видимо в том что нужны все хелперы в одном тельце, а не только один (специализированный)Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 18, 2016, 17:51 Цитировать Видимо в том что нужны все хелперы в одном тельце, а не только один (специализированный) Что значит все хелперы в одном тельце? Какие все? Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 18, 2016, 18:32 Проблема в том, что в doStuff() нужно не только дергать методы в зависимости от типа _A, но и реагировать на их результаты в зависимости от типа _A.
При этом возможен доступ к приватным членам T, что через хелпер не получится (ну, только если их зафрендить, или сделать спец. интерфейс для доступа). А хотелось бы просто такое: Код: void T<A>::doStuff() Т.е. такой условный свитч, который "умно" инстанциирует части кода doStuff() в зависимости от того, кто есть A. В принципе, нечто вроде сишного #ifdef... #endif, но для шаблонов. Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 18, 2016, 18:51 Если очевидна/налицо "динамика", то зачем делать ее "статикой"? Приведетесь dynamic_cast<>, не облезете. dynamic_cast<> прекрасно работает (пока на нем родимом все и держится). Но это все же runtime. А главный плюс шаблонов - это "когда компилятор все разрулит", вроде бы.. ??? Внутри каждого инстанциированного класса динамика не нужна, т.к все зависит тока от типа A. Вот решил воспользоваться фичей языка... а похоже, что без гемороюшки тут никак :( Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 18, 2016, 19:35 Цитировать Вот решил воспользоваться фичей языка... а похоже, что без гемороюшки тут никак Да нет, такой меташаблонный case вполне реализуется) Напишу, выложу)Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 18, 2016, 20:20 Вобщем вот примерный меташаблонный вариант swithа:
Код
Здесь лямбда будет видеть все приватные члены и прочие методы.. P.S. Но к этому варианту нужно относиться только лишь как к некой технической возможности, не более.. Просто как к альтернативе.. Но это, на мой взгляд, плохое решение (хотя я и не знаю, Ваших замыслов и т.д.. ). Плохое в том смысле, что если появится новый наследник от класса A, то помимо специализации хелпера, дополнительно придётся лезть в код метода T<Obj>::doStuff.. Мне это кажется весьма сомнительным.. Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 18, 2016, 23:18 P.S. Но к этому варианту нужно относиться только лишь как к некой технической возможности, не более.. Просто как к альтернативе.. Но это, на мой взгляд, плохое решение (хотя я и не знаю, Ваших замыслов и т.д.. ). Плохое в том смысле, что если появится новый наследник от класса A, то помимо специализации хелпера, дополнительно придётся лезть в код метода T<Obj>::doStuff.. Мне это кажется весьма сомнительным.. Да, боюсь, на практике такая возможность будет несколько... скажем так... неадекватна по затратам по отношению к результатам :( Гуглы и стековерфлоу я уже перекопал, там вообще все глухо. Получается, что ни одна существующая реализация языка не поддерживает непосредственную инстанциацию фрагментов кода. Хотя, опять же, как по мне - возможность была бы довольно мощной, а кроме того, не вижу проблем в имплементации для компилятора. Статически выполнить сравнение типов параметров шаблона при инстанцировании и активировать нужные куски кода - это как то не особо сложно звучит, сишный препроцессор, не более. В общем, "рантайм наше все", спасибо откликнувшимся :) Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 19, 2016, 06:58 Получается, что ни одна существующая реализация языка не поддерживает непосредственную инстанциацию фрагментов кода. "Запретный плод" всегда кажется "довольно мощным" :) Как я понимаю идея этих "хвостиков" (traits) в том что основной класс пишется один раз, а потом, отдельно дописываются хвосты для инстансов по мере их поступления. Так смысл есть (хотя конечно все равно мерзость). Но у Вас др ситуация - Вы хотите "куски кода", т.е. Вы уже согласны править основной класс всякий раз. Тогда чего затевать темплейты?Хотя, опять же, как по мне - возможность была бы довольно мощной, а кроме того, не вижу проблем в имплементации для компилятора. Кстати интересно, а напр при такой проверке Код: if (typeid(some_member) == typeid(some_class)) Да, боюсь, на практике такая возможность будет несколько... скажем так... неадекватна по затратам по отношению к результатам :( Во-во-во, недавно в др теме (безуспешно) пытался объяснить то же самоеНазвание: Re: Специализация шаблона для базового класса Отправлено: Old от Сентябрь 19, 2016, 08:50 понадобилась довольно простая вещь. Racheengel, а у вас не возникает ощущения, что вы делаете что-то не то. :)Как-то это уж очень топорно получается. Может стоит пересмотреть интерфейс у дерева классов или сделать не один шаблон, а несколько... Сейчас для абстракной задачи сложно что-то посоветовать, но я бы такое в боевой код не тащил, даже если бы C++ это позволял. :) Название: Re: Специализация шаблона для базового класса Отправлено: __Heaven__ от Сентябрь 19, 2016, 11:04 Быть может есть возможность в классе A написать чистый виртуальный метод doStuff, который исполнит желаемое...
Название: Re: Специализация шаблона для базового класса Отправлено: __Heaven__ от Сентябрь 19, 2016, 11:14 Быть может даже и виртуальность не нужна. Обычная перегрузка doStuff поможет?
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 11:14 Основная идея (проблема) в следующем.
Есть закрытая гуй-библиотека, которая содержит разные графические классы. Некоторые из них имеют общего предка, некоторые нет. У меня задача расширить функциональность всех этих классов одинаковым образом. В настоящее время это сделано так, что параллельно к библиотечным существуют "свои" расширяющие классы. Для того, чтого они могли сосуществовать с гуй-системой, они обязаны быть наследниками библиотечных объектов. Решено это с помощью multiple inheritance: "свои" классы наследуются от "расширителей" и от гуй-объектов одновременно. Т.е. так: // это гуй-библиотека class GuiBase; class GuiObjectA : public GuiBase; class GuiObjectB : public GuiObjectB; class GuiObjectC : public GuiBase; --- // это наши "расширители" class ItemBase; class ExtItem1: public ItemBase; class ExtItem2: public ItemBase; --- // это "расширенные" гуй-классы (идея) class GuiItemA: public GuiObjectA, public ExtItem1; class GuiItemB: public GuiObjectB, public ExtItem1; class GuiItemA2: public GuiObjectA, public ExtItem2; class GuiItemC2: public GuiObjectC, public ExtItem2; и т.д. проблема в том, что "расширители" должны иметь доступ к гуи-объектам (что при идее выше не будет работать). Поэтому был слелан соответсвующий темлейт типа template <class Gui, class Extender> class GuiItem: public Gui, public Extender // тут общий функционал, связывающий Gui и Extender и далее class GuiItemA: public GuiItem<GuiObjectA, ExtItem1>; class GuiItemC2: public GuiItem<GuiObjectC, ExtItem2>; ... в некоторых случаях имплементации GuiItem требуется различать между GuiObjectA и GuiObjectC. Решено с помощью рантайма, хотя мне казалось, что тут как раз шаблоны - самое оно. Но как-то не срастается... Название: Re: Специализация шаблона для базового класса Отправлено: __Heaven__ от Сентябрь 19, 2016, 11:25 Накидал небольшой примерчик. Для вашей задачи вроде должен подойти. Но, вроде, тут надо идти другими путями.
https://ideone.com/zeBvoW Код
Цитировать A B C Название: Re: Специализация шаблона для базового класса Отправлено: Old от Сентябрь 19, 2016, 11:29 проблема в том, что "расширители" должны иметь доступ к гуи-объектам (что при идее выше не будет работать). Почему не будет работать?Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 11:40 проблема в том, что "расширители" должны иметь доступ к гуи-объектам (что при идее выше не будет работать). Почему не будет работать?Потому что, если написать так: class GuiItemA: public GuiObjectA, public ExtItem1; то ExtItem1 не "видит", что такое GuiObjectA. Это "знает" только GuiItemA. Но "знать" он должен в зависимости от того, что есть GuiObject... Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 11:42 Быть может даже и виртуальность не нужна. Обычная перегрузка doStuff поможет? В том и проблема, что перегружать его надо внутри шаблона, в зависимости от его аргумента (GuiObjectX). Я как раз этого и хотел добиться, но пока не срастаеццо :( Название: Re: Специализация шаблона для базового класса Отправлено: Old от Сентябрь 19, 2016, 11:47 то ExtItem1 не "видит", что такое GuiObjectA. Так может:Это "знает" только GuiItemA. Но "знать" он должен в зависимости от того, что есть GuiObject... Код
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 11:55 Тогда проблема в том, что ExtItem1 будет темплейтом.
А в последующем коде повсеместно юзается dynamic_cast<ExtItem*>(...), что с темплейтом не прокатит :( Название: Re: Специализация шаблона для базового класса Отправлено: __Heaven__ от Сентябрь 19, 2016, 12:08 Racheengel, имхо, dynamic_cast можно виртуалами заменить. также, посмотрите такую конструкцию
Код И мне кажется, что вы не посмотрели код в #16 Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 14:43 Racheengel, имхо, dynamic_cast можно виртуалами заменить. также, посмотрите такую конструкцию Код И мне кажется, что вы не посмотрели код в #16 Посмотрел, это в принципе практически то же, что и m_ax предложил. Проблема тут в том, что: 1. из someClass.print() нельзя просто получить доступ к приватным членам вызывающего класса. 2. не все классы имеют метод print(), для некоторых надо вызывать нечто иное. Виртуалы, _возможно_, были бы решением. Правда, в них придется тащить кучу временных параметров... Хотя неясно, как поведет себя компиль в таком случае: class Base; class Item: Base; class Item2: Item; virtual void doStuff(Base* base) { // код для Base } virtual void doStuff(Item2* item) { // код для Item2, но Item2 - тоже наследник Base :( } имхо тут конфликт будет... Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 19, 2016, 15:50 Цитировать из someClass.print() нельзя просто получить доступ к приватным членам вызывающего класса. Соберите тогда все приватные члены в один класс и передавайте объект этого класса в хелпер)Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 19, 2016, 15:59 Основная идея (проблема) в следующем. Ну вообще-то это "фабрика" - создать новый класс из разных (или слабо-связных) исходных.Есть закрытая гуй-библиотека, которая содержит разные графические классы. Некоторые из них имеют общего предка, некоторые нет. У меня задача расширить функциональность всех этих классов одинаковым образом. В настоящее время это сделано так, что параллельно к библиотечным существуют "свои" расширяющие классы. Для того, чтого они могли сосуществовать с гуй-системой, они обязаны быть наследниками библиотечных объектов. Название: Re: Специализация шаблона для базового класса Отправлено: Old от Сентябрь 19, 2016, 17:29 Ну вообще-то это "фабрика" - создать новый класс из разных (или слабо-связных) исходных. Нет. Фабрика это когда один объект создает другие объекты.Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 18:58 Цитировать из someClass.print() нельзя просто получить доступ к приватным членам вызывающего класса. Соберите тогда все приватные члены в один класс и передавайте объект этого класса в хелпер)А методы? :) Хелперы френдить? Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 19, 2016, 19:23 Цитировать А методы? :) Хелперы френдить? Так с таким раскладом здесь проще специализировать ваш T для каждого типа.. Если там всё так сильно друг на друге повязано.. Ну и вообще над архитектурой думать-думать и думать, а уже потом писать) Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 19, 2016, 23:53 Ну и вообще над архитектурой думать-думать и думать, а уже потом писать) Так уже все "придумано до нас" и изменениям не подлежит. Наше дело - "расширить" :( Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 20, 2016, 22:11 Попробовал вариант с хелпером... появилась такая проблема: допустим, у нас классы
class A; class B; class B1: public B; class B2: public B; template<> class T<A>; template<> class T<B>; Теперь, мне нужно инстанциировать все возможные T<B1>, T<B2>, и т.д. Но компилятор говорит, что "нету специализаций для B1 и B2". Это странно, т.к. я явно указал T<B> для базового класса. По идее, такие же правила должны действовать и для наследников ??? Название: Re: Специализация шаблона для базового класса Отправлено: m_ax от Сентябрь 20, 2016, 23:17 Нет, T<B> и T<B1> - это разные типы с точки зрения языка..
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 20, 2016, 23:42 Нет, T<B> и T<B1> - это разные типы с точки зрения языка.. Это довольно странно, ведь налицо возможность "статической виртуализации". Для компилятора в принципе здесь нет проблемы неоднозначности. Он видит, что для B1 нет специализации, идет вверх по иерархии, находит B и генерирует код... По крайней мере так было бы логично, имхо. Название: Re: Специализация шаблона для базового класса Отправлено: ViTech от Сентябрь 21, 2016, 13:26 ... Теперь, мне нужно инстанциировать все возможные T<B1>, T<B2>, и т.д. Но компилятор говорит, что "нету специализаций для B1 и B2". Это странно, т.к. я явно указал T<B> для базового класса. По идее, такие же правила должны действовать и для наследников ??? Код
Но если уровней наследования больше, то какую специализацию использовать? Код
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 21, 2016, 15:01 Цитировать Но если уровней наследования больше, то какую специализацию использовать? Ту, для которой специализирован ближайший предок. то есть для B21 это будет B2. Для В1 будет В. Название: Re: Специализация шаблона для базового класса Отправлено: ViTech от Сентябрь 21, 2016, 15:33 Ту, для которой специализирован ближайший предок. то есть для B21 это будет B2. Для В1 будет В. Это в данном частном случае вы так решили :). Но в общем случае компилятору что делать? В С++ поддерживается множественное наследование, не всегда всё сводится к простым случаям "первый ближайший предок". И определить этого первого ближайшего предка, похоже, не так просто. В std type_traits я такого не встречал. Гуглить "c++ primary|direct base class trait". Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 21, 2016, 15:49 Основная идея (проблема) в следующем. До этого момента примерно понятно. Есть классы унаследованные от разных базовых (от своих + из либы 1 + из либы 2)Есть закрытая гуй-библиотека, которая содержит разные графические классы. Некоторые из них имеют общего предка, некоторые нет. У меня задача расширить функциональность всех этих классов одинаковым образом. В настоящее время это сделано так, что параллельно к библиотечным существуют "свои" расширяющие классы. Для того, чтого они могли сосуществовать с гуй-системой, они обязаны быть наследниками библиотечных объектов. Решено это с помощью multiple inheritance: "свои" классы наследуются от "расширителей" и от гуй-объектов одновременно. Т.е. так: // это гуй-библиотека class GuiBase; class GuiObjectA : public GuiBase; class GuiObjectB : public GuiObjectB; class GuiObjectC : public GuiBase; --- // это наши "расширители" class ItemBase; class ExtItem1: public ItemBase; class ExtItem2: public ItemBase; --- // это "расширенные" гуй-классы (идея) class GuiItemA: public GuiObjectA, public ExtItem1; class GuiItemB: public GuiObjectB, public ExtItem1; class GuiItemA2: public GuiObjectA, public ExtItem2; class GuiItemC2: public GuiObjectC, public ExtItem2; и т.д. проблема в том, что "расширители" должны иметь доступ к гуи-объектам (что при идее выше не будет работать). А тут как-то не очень, "нить теряется"Поэтому был слелан соответсвующий темлейт типа template <class Gui, class Extender> class GuiItem: public Gui, public Extender // тут общий функционал, связывающий Gui и Extender и далее class GuiItemA: public GuiItem<GuiObjectA, ExtItem1>; class GuiItemC2: public GuiItem<GuiObjectC, ExtItem2>; ... в некоторых случаях имплементации GuiItem требуется различать между GuiObjectA и GuiObjectC. Решено с помощью рантайма, хотя мне казалось, что тут как раз шаблоны - самое оно. Но как-то не срастается... У меня задача расширить функциональность всех этих классов одинаковым образом. Можно пример класса и метода что Вы хотите получить?Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 21, 2016, 16:26 Но в общем случае компилятору что делать? В С++ поддерживается множественное наследование, не всегда всё сводится к простым случаям "первый ближайший предок". И определить этого первого ближайшего предка, похоже, не так просто. А тут и не надо ничего решать. Достаточно следовать тем же правилам, которые используются при dynamic_cast. Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 21, 2016, 16:41 Цитировать Можно пример класса и метода что Вы хотите получить? class A; class B: public A; class B1: public B; template<class A> class T { ... stuff(); // A::stuff(); ... } template<> class T<A> { stuff(); // вызвать A::stuff } template<> class T<B> { stuff(); // вызвать B::stuff } А теперь хотим так: class C: public T<B1> { stuff(); // поскольку B1 наследник от В, то вызвать B::stuff - но не работает, ибо "нет специализации для В1" } Название: Re: Специализация шаблона для базового класса Отправлено: ViTech от Сентябрь 21, 2016, 17:41 А тут и не надо ничего решать. Достаточно следовать тем же правилам, которые используются при dynamic_cast. Я тоже много всего хочу от С++ :). Код
Что компилятору делать в этом случае? Даже в случае с dynamic_cast, к чему приводить будете? Наверняка тут и других особенностей хватает. Это вам в конкретном случае понадобилась специализация по первому предку. А другим в общем случае может не нужно такое поведение, и необходимо, чтобы использовалось общее определение шаблона. Как им тогда указывать, что нужно использовать общее определение, а не специализацию по первому предку? Буквально на днях была статья на хабре в тему: Наследование реализаций: закопайте стюардессу (https://habrahabr.ru/post/310314/). Когда приходится городить такое количество костылей, то проблема, скорей всего, лежит уровнем выше, в архитектуре. Понятно, что принимать стороннюю библиотеку приходится так, как она есть. И если ставится задача расширять коров с помощью коней, то без извращений не обойтись :). Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 21, 2016, 18:23 Цитировать Что компилятору делать в этом случае? Даже в случае с dynamic_cast, к чему приводить будете? Ну тут все очевидно. Если воспользоваться принципом dynamic_cast, получим такое: T<D> d; if (dynamic_cast<A*>(&d)) { // первая специализация - А - совпала ? тогда мы А :) } else if (dynamic_cast<B*>(&d)) { // а тут мы В } else { // а тут ни А, ни В } Т.е. первая подходящая специализация, для D - это А, что соответствует порядку наследования. Название: Re: Специализация шаблона для базового класса Отправлено: ViTech от Сентябрь 21, 2016, 18:48 if (dynamic_cast<A*>(&d)) { // первая специализация - А - совпала ? тогда мы А :) } else if (dynamic_cast<B*>(&d)) { // а тут мы В } else { // а тут ни А, ни В } Чем родитель "B" хуже родителя "A"? :) Но это лирика. Можно попробовать вести параллельную иерархию с T: Код
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 21, 2016, 20:42 Цитировать Чем родитель "B" хуже родителя "A"? Порядком наследования. Было бы Код: class C: public B, public A Цитировать Можно попробовать вести параллельную иерархию с T: Можно, но проблема в том, что не-темплейтные классы может создавать пользователь, а он понятия не имеет об иерархии T :( поэтому мы и не можем специфицировать каждый наследник в отдельности... Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 22, 2016, 08:42 Не въезжаю
template<class A> Как зовется stuff? Ведь T не наследник аргумента Aclass T { ... stuff(); // A::stuff(); ... } template<> Зачем специализация, чем не устраивал общий шаблон?class T<A> { stuff(); // вызвать A::stuff } Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 22, 2016, 11:26 Извиняюсь, немного ошибся, должно быть так:
Код: template<class A> Т.е. создаем наследника от А. Специализация нужна для того, что не все А имеют одинаковые методы. Например, для А надо вызвать A::stuff(), а для C надо и С::stuff(), и С::someAnotherStuff(): class C: public B { virtual void stuff(); virtual void someAnotherStuff(); }; Шаблон про someAnotherStuff() не знает, т.к. нет возможности проверить, что есть C при инстанциировании T<C>. Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 22, 2016, 16:22 Т.е. создаем наследника от А. Все равно цель от меня ускользает, нет четкого представления что нужно. Хорошо, про исходные классы Вы уже неск раз говорили, допустим все как-то получилось/связалось, как бы Вы хотели использовать готовое?Специализация нужна для того, что не все А имеют одинаковые методы. Например, для А надо вызвать A::stuff(), а для C надо и С::stuff(), и С::someAnotherStuff(): Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 22, 2016, 16:50 Если более конкретно, то речь о настройке параметров объектов.
В зависимости от того, кто есть А, а кто С, надо вызывать различные методы. Темплейт - это некий аналог фасада. Грубо говоря, у него есть метод updateParams(), торчащий наружу. А уже внутри него надо реализовать вызовы различных методов из расширяемых классов, в зависимости от их типа. Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 23, 2016, 11:13 А если сначала так
Код А потом так Код
Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 23, 2016, 11:19 Вот именно так сейчас и сделано :)
Просто думалось, что темплейты это позволяют без свистоплясок порешать... Название: Re: Специализация шаблона для базового класса Отправлено: Igors от Сентябрь 23, 2016, 11:23 Вот именно так сейчас и сделано :) Не понял. Так они вроде и решают (ну почти без :)). Чем же это решение "нешаблонно"?Просто думалось, что темплейты это позволяют без свистоплясок порешать... Название: Re: Специализация шаблона для базового класса Отправлено: Racheengel от Сентябрь 23, 2016, 11:55 Ну, оно то шаблонно, но dynamic_cast присутствует)
А была надежда, что можно избежать и этого... |