Частичная инициализация шаблонного класса

Тема в разделе "LANGS.C", создана пользователем cupuyc, 6 дек 2010.

  1. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    Здравствуйте. Есть некоторый класс

    Код (Text):
    1. template <int x, bool flag>
    2. class A
    3. {
    4. private:
    5. public:
    6.   template <class T>
    7.   void f();
    8. };
    Нужно написать 2 реализации функции f для параметра flag = true и для параметра flag = false. Не могу сообразить как это сделать. Так будет правильно?

    Код (Text):
    1. template <class T>
    2. template <int x>
    3. void A<x, true>::f<T>()
    4. {
    5. }
    6.  
    7. template <class T>
    8. template <int x>
    9. void A<x, false>::f<T>()
    10. {
    11. }
     
  2. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    Ещё вопрос по частичной инициализации функций. Пусть есть функция

    Код (Text):
    1. template <int x, bool b>
    2. void func();
    Я хочу определить 2 реализации для b = true и для b = false. Но так не катит..

    Код (Text):
    1. template <int x>
    2. void func<x, true>()
    3. {
    4. }
    5.  
    6. template <int x>
    7. void func<x, false>()
    8. {
    9. }
     
  3. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    cupuyc

    наверно только ветвиться
     
  4. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    Задачка на самом деле такая. Я хочу в своей библиотеке сделать флажок b_use_exceptions в зависимости от которого будет происходить генерация эксепшнов или нет. Нужно это для того, что некоторые, используемые мной компиляторы (н-п IAR for ARM) не поддерживают работу с исключениями. Сделал что-то типа этого..


    Код (Text):
    1.   static bool const use_exceptions = true;
    2.  
    3.   template <int dummy, bool b_use_exceptions>
    4.   class BasicException
    5.   {
    6.   public:
    7.     template <class t_exception>
    8.     static void do_throw(const t_exception& exception);
    9.   };
    10.  
    11.   template <class t_exception>
    12.   template <int dummy>
    13.   void BasicException<dummy, true>::do_throw<t_exception>(const t_exception& exception)
    14.   {
    15.     throw exception;
    16.   }
    17.  
    18.   template <class t_exception>
    19.   template <int dummy>
    20.   void BasicException<dummy, false>::do_throw<t_exception>(const t_exception& exception)
    21.   {
    22.   }
    23.  
    24.   typedef BasicException<0, use_exceptions> Exception;
    и далее в программе

    Код (Text):
    1.       if (bag)
    2.       {
    3.         Exception::do_throw(std::exception("invalid argument"));
    4.         return;
    5.       }
     
  5. wsd

    wsd New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2007
    Сообщения:
    2.824
    cupuyc
    делай макрос( #define), платформочувствительный )
     
  6. RedLord

    RedLord Member

    Публикаций:
    0
    Регистрация:
    23 июн 2005
    Сообщения:
    183
    Адрес:
    Ukraine
    такое не пройдет
     
  7. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    cupuyc
    Частичная специализация шаблонных ф-ций поддерживается только в С++ 0x.
    Сделайте ф-цию статическим членом шаблонного класса с нужными специализациями.
    Т.е. параметры шаблона ф-ции вынесите в шаблон класса, а саму ф-цию оставьте нешаблонной.
     
  8. cupuyc

    cupuyc New Member

    Публикаций:
    0
    Регистрация:
    2 апр 2009
    Сообщения:
    763
    код, приведённый в #4 правилен?
     
  9. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    cupuyc
    Насколько я могу судить, компилироваться такое не будет.

    А вот так - должно:
    Код (Text):
    1.   template <>
    2.   template <class t_exception>
    3.   void BasicException<0, false>::do_throw<t_exception>(const t_exception& exception)
    4.   {
    5.   }
    Впрочем, смотря насколько продвинут ваш компилятор.
     
  10. KeSqueer

    KeSqueer Сергей

    Публикаций:
    0
    Регистрация:
    19 июл 2007
    Сообщения:
    1.183
    Адрес:
    Москва
    cupuyc
    Не особо шарю в C++, но получил то, что хотел (компилируется MSVC 2010, Comeau 4.3.9 ALPHA C++03 mode):
    Код (Text):
    1. #include <stdexcept>
    2.  
    3. static const bool use_exceptions = true;
    4.  
    5. template <bool>
    6. class BaseException {
    7.  public:
    8.   template <class t_exception>
    9.   static void do_throw(const t_exception &exception);
    10. };
    11.  
    12. template <> template <class t_exception>
    13. void BaseException<true>::do_throw(const t_exception &exception) { throw exception; }
    14.  
    15. template <> template <class t_exception>
    16. void BaseException<false>::do_throw(const t_exception &exception) {}
    17.  
    18. typedef BaseException<use_exceptions> Exception;
    19.  
    20. int main(void) {
    21.   Exception::do_throw(std::exception());
    22.   return 0;
    23. }
    У меня к Вам два вопроса:
    1) Не смущает ли Вас то, что Exception::do_throw(std::exception()); в любом случае вызывает конструктор/деструктор исключения?
    2) Почему template <class t_exception> static void do_throw(const t_exception &exception);, а не static void do_throw(const std::exception &exception);? Тогда бы, на мой взгляд, было куда симпатичнее:
    Код (Text):
    1. #include <stdexcept>
    2.  
    3. static const bool use_exceptions = true;
    4.  
    5. template <bool>
    6. class BaseException {
    7.  public:
    8.   static void do_throw(const std::exception &exception);
    9. };
    10.  
    11. template <>
    12. void BaseException<true>::do_throw(const std::exception &exception) {
    13.   throw exception;
    14. }
    15.  
    16. template <>
    17. void BaseException<false>::do_throw(const std::exception &exception) {}
    18.  
    19. typedef BaseException<use_exceptions> Exception;
    20.  
    21. int main(void) {
    22.   Exception::do_throw(std::exception());
    23.   return 0;
    24. }