На главную Наши проекты:
Журнал   ·   Discuz!ML   ·   Wiki   ·   DRKB   ·   Помощь проекту
ПРАВИЛА FAQ Помощь Участники Календарь Избранное RSS
msm.ru
Модераторы: Qraizer, Hsilgos
  
> Статическая специализация шаблона
    Есть шаблонный контейнер, для которого можно задавать параметрами размер

    Схематично
    ExpandedWrap disabled
      template <std::size_t N> class Some {
      public:
          static constexpr std::size_t SIZE = N;
          static const Some UNKNOWN;
          using container = std::array<uchar, N>;
          using value_type = typename container::value_type;
          Some(value_type value)
          {
              m_array.assign(value);
          }
          Some(const std::initializer_list<value_type>& list)
          {
              ...
          }
          ~Some() {}
      private:
          container m_array;
      };


    для каждого специализированного шаблона задается нулевое значение специализацией
    ExpandedWrap disabled
      template <uint N> const typename Some<N> Some<N>::UNKNOWN(0x00);
      using Container = Some<100>;


    Так вот хотел скрыть специализацию, что то вроде
    ExpandedWrap disabled
      template <std::size_t N> class Some {
      public:
          static constexpr std::size_t SIZE = N;
          using container = std::array<uchar, N>;
          using value_type = typename container::value_type;
      private:
          static const Some<N> UNKNOWN (0x00);
          container m_array;
      };


    почему так нельзя, а внешняя специализация канает?
      А что есть 0x00? В классе Some нет же такого конструктора с параметром?
        Цитата xbarmaglot @
        для каждого специализированного шаблона задается нулевое значение специализацией

        Зачем тебе это вообще нужно? Сделай конструктор по-умолчанию и всё
        ExpandedWrap disabled
          Some::Some()
          : m_array({0})
          {
          }
          Цитата JoeUser @
          А что есть 0x00? В классе Some нет же такого конструктора с параметром?

          в первом примере есть. просто не повторял для краткости

          Цитата Олег М @
          Зачем тебе это вообще нужно? Сделай конструктор по-умолчанию и всё

          чтобы можно было проверять контейнер любого размера на заданное значение.

          Например
          ExpandedWrap disabled
            using Container1 = Some<100>;
            using Container2 = Some<1000>;
             
            Container1 c1;
            Container2 c3;
             
            ...
             
            if (c1 != Container1::UNKNOWN) ...
            if (c2 != Container2::UNKNOWN) ...


          только вместо этого хотел метод сделать
          ExpandedWrap disabled
            Some{
            private :
                static const UNKNOWN;
             
            public :
               bool valid(void) const { return (*this != UNKNOWN); }
            }


          Этих статических значений может быть много с разными значениями
            Цитата
            почему так нельзя, а внешняя специализация канает?

            Потому что это не специализация, а определение (definition). Это для constexpr определения как такового не требуется, а для статического члена класса (не важно, шаблонного или обычного) требуется определение в одном и только одном компилируемом файле. То есть в
            ExpandedWrap disabled
              class My {
              public:
              static int n;
              };

            присутствует объявление (declaration) статического члена My::n. Если вспомнить, что статический член класса - это по сути просто глобальная переменная с именем класса в качестве пространства имен и некоторым ограничением доступа (в данном случае - нет), то это что-то типа
            ExpandedWrap disabled
              namespace My {
              extern int n;
              };

            Эта объявленная переменная должна быть определена (и, возможно, проинициализирована) в компилируемом файле, причем только в одном, типа того:
            ExpandedWrap disabled
              int My::n = 0;
              Цитата xbarmaglot @
              чтобы можно было проверять контейнер любого размера на заданное значение.

              Метод конечно дико мутный. Но если так уж хочется, сделай тогда статический метод
              ExpandedWrap disabled
                template <std::size_t N>
                class Some
                {
                public:
                ...............
                  static const Some &Unknown()
                  {
                     static Some _some;
                     return _some;
                  }
                ................
                }
                понял - спасибо
                0 пользователей читают эту тему (0 гостей и 0 скрытых пользователей)
                0 пользователей:


                Рейтинг@Mail.ru
                [ Script execution time: 0,0361 ]   [ 17 queries used ]   [ Generated: 19.04.24, 04:38 GMT ]