Объявление экземпляра явной специализации шаблона в обычном классе - PullRequest
3 голосов
/ 03 сентября 2010

Я не могу заставить это скомпилировать вообще.Я не могу быть возможно, но я не знаю, почему это не должно быть.

class A {
  template <typename T> 
  class B {
   int test() { return 0; }
  };
  //template <> class B<int>; <-with this, namepace error
  B<int> myB_;
 };

 template <> class A::B<int> {
  int test() {
   return 1;
  }
 };

Как представляется, компилятор жалуется, что "явная специализация" class A :: B "должна быть объявлена ​​перед использованием«.Если я пытаюсь предоставить объявление froward в закомментированной строке, компилятор жалуется: «Явная специализация« B »должна быть объявлена ​​в пространстве имен, содержащем шаблон».Мы используем 2 разных компилятора здесь.Эта ошибка взята из компилятора IBM "xl" в AIX, но при компиляции в наших системах Sun я получаю похожие ошибки с разной степенью детализации.Похоже на уловку-22.

Очевидно, это очень надуманный, упрощенный пример, но он представляет проблему.Я хочу определить класс шаблона внутри класса, потому что класс шаблона релевантен только содержащему классу.Не должно быть доступа к шаблону извне класса.

Я что-то упустил?

Ответы [ 3 ]

3 голосов
/ 03 сентября 2010

Вы правы.Это невозможно сделать (насколько я знаю).Ваше объявление члена вызывает неявную реализацию до того, как была объявлена ​​явная специализация.Но как бы вы хотели это объявить?Вы не можете сделать это в рамках класса.Другие чувствовали, что это ужасное ограничение .

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

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

0 голосов
/ 03 сентября 2010

B не шаблонный класс, и вы пытаетесь его специализировать.Это причина ошибки.Вы можете проверить эти две ошибки C2913 и C3413 .Это то, что вы ищете?

class A
{
   template<class T>
   class B
   {
      inline int test()
      {
         return 0;
      }
   };
   A::B<int> myB_;
};
0 голосов
/ 03 сентября 2010

Вы можете обойти проблему, используя неназванное пространство имен для конфиденциальности:

namespace {

  template <typename T> 
  class B {
   int test() { return 0; }
  };

  template <> class B<int> {
    int test() {
      return 1;
    }
};

}

class A {
  B<int> myB_;
};

Это скомпилируется, но если A должно быть видно за пределами этого модуля компиляции, вам потребуется более сложныймашины ( например , интерфейс и фабрика или Pimpl ).

...