在常规类中声明模板的显式特化的实例

时间:2010-09-03 12:52:33

标签: c++ templates nested specialization explicit

我根本无法编译。我可能不可能,但我不知道为什么不应该这样。

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;
  }
 };

看起来编译器抱怨“显式特化”类A :: B“必须在使用之前声明。” 如果我尝试在注释行中提供froward声明,编译器会抱怨 “显式特化”B“必须在包含模板的命名空间中声明。” 我们在这里使用2个不同的编译器。此错误来自IBM在AIX上的“xl”编译器,但在我们的Sun系统上进行编译时,我会遇到类似的错误。 这似乎是一个抓住22。

显然,这是一个非常人为的,简单化的例子,但它代表了问题。 我想在类中定义一个模板类,因为模板类只与包含类相关。不应该从课堂外访问模板。

我错过了什么吗?

3 个答案:

答案 0 :(得分:3)

你是对的。这是不可能的(据我所知)。在声明显式特化之前,您的成员声明会导致隐式实例化。但是你想怎么声明呢?你不能在课堂范围内这样做。其他人感到this is an ugly restriction

你可以通过使类成员成为指针来解决这个问题。这不需要在该点隐式实例化类,而是在最后创建对象的位置。我意识到这是一个丑陋的工作。所以最好找到其他方法来做到这一点。

例如,在类范围中允许部分特化。因此,您可以添加一个虚拟模板参数,然后您可以在成员声明之前在类中对此进行专门化。同样,我觉得这很难看,但我觉得它不会打扰那么多东西。

答案 1 :(得分:0)

您可以通过使用未命名的隐私命名空间来解决此问题:

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

答案 2 :(得分:0)

B不是模板类,您正在尝试将其专门化。这是导致错误的原因。您可以检查这两个错误C2913C3413。 这是你在找什么?

class A
{
   template<class T>
   class B
   {
      inline int test()
      {
         return 0;
      }
   };
   A::B<int> myB_;
};