Почему частичная специализация вложенного шаблона класса допускается, а полная - нет?

Как это

String является «hello», а требуемое заполнение - 15 с «0» левой панелью

String ax="Hello";
while(ax.length() < 15) ax="0"+ax;
42
задан pterodragon 11 July 2018 в 09:58
поделиться

4 ответа

Я предполагаю, почему это происходит: полные специализации больше не являются «шаблонными классами / функциями», они являются «настоящими» классами / методами и должны иметь реальные (видимые для компоновщика) символы. Но для полностью специализированного шаблона внутри частично специализированного это было бы неверно. Вероятно, это решение было принято просто для того, чтобы упростить жизнь разработчикам компиляторов (и усложнить жизнь кодировщикам в процессе :П ).

27
ответ дан 26 November 2019 в 23:57
поделиться

Вы можете обойти это поведение, делегировав реальную работу другой структуре:

namespace detail
{
  template <class T, class U>
  struct InnerImpl {};
}

template <class T>
struct Outer
{
  template <class U>
  struct Inner: detail::InnerImpl<T,U>
  {
  };
};

Теперь вы можете специализироваться InnerImpl по своему усмотрению

7
ответ дан 26 November 2019 в 23:57
поделиться

Подтверждая аргумент Вергилия (он был быстрее, чем я, опубликовавший то же обоснование), рассмотрите следующее:

template<typename T1>
class TOuter
  {
  public:
    template<typename T2>
    class TInner
      {
      public:
        T1 m_1;
        T2 m_2;
      };
  };

template<typename T1>
template<>
class TOuter<T1>::TInner<float>
  {
  public:
    T1    m_1;
    float m_2;
 };

Является ли TInner полностью специализированным или частично специализированным из-за T1?

Редактировать:

После рассмотрения некоторых других комментариев кажется, что вы хотите иметь полную специализацию на основе параметра шаблона во внешнем классе. Если вы вложите реализацию внутреннего класса, это будет работать в Visual Studio 2005:

template<typename T1>
class TOuter
  {
  public:
    template<typename T2>
    class TInner
      {
      public:
        std::string DoSomething() { return "Inner - general"; }
        T2 m_2;
      };

    template<>
    class TInner<T1>
      {
      public:
        std::string DoSomething() { return "Inner - special"; }
        T1 m_1;
      };
  };

TOuter :: TInner правильно будет специализацией TInner. Мне не удалось его скомпилировать с реализацией вне шаблона.

4
ответ дан 26 November 2019 в 23:57
поделиться

Стандарт C ++ явно запрещает полную специализацию классов шаблонов элементов в первом случае. Согласно 14.7.3 / 18:

В явном объявлении специализации для члена шаблона класса или шаблона члена, который появляется в области пространства имен, шаблон члена и некоторые из включающих его шаблонов классов могут оставаться неспециализированный, , за исключением того, что объявление не должно явно специализировать шаблон члена класса, если его включающие шаблоны класса также не являются явно специализированными .

8
ответ дан 26 November 2019 в 23:57
поделиться
Другие вопросы по тегам:

Похожие вопросы: