【问题标题】:Declaring an instance of an explicit specializtion of a template within a regular class在常规类中声明模板的显式特化实例
【发布时间】:2010-09-03 12:52:33
【问题描述】:

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

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 系统上编译时,我得到了类似的错误,但措辞不同。 这似乎是一个catch-22。

显然,这是一个高度做作、简单化的示例,但它代表了问题所在。 我想在一个类中定义一个模板类,因为模板类只与包含类有关。不应从类外部访问模板。

我错过了什么吗?

【问题讨论】:

  • 使用四个空格缩进代码(或选择代码并按Ctrl+K)。
  • 这不应该像我们看到的那样编译,即使没有专门化。但那是因为 已被站点删除,将它们与 HTML 标记混淆。请选择代码部分并在发布时使用“101010”工具栏按钮将它们标记为 - 这将完全保留代码。否则,根据标准,在包含类之外进行专业化是可以的。但请恢复缺失的代码部分,以使讨论生效。
  • 在您使用 myB_ 的情况下,您可能会考虑使用 PIMPL 习惯用法,此时不需要 B

标签: c++ templates nested specialization explicit


【解决方案1】:

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

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

例如,类范围内允许部分特化。所以你可以添加一个虚拟模板参数,然后你可以在成员声明之前在类中专门化它。同样,我觉得这很难看,但我觉得它不会打扰太多事情。

【讨论】:

    【解决方案2】:

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

    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)。

    【讨论】:

      【解决方案3】:

      B 不是模板类,您正在尝试对其进行专门化。这就是错误的原因。您可以检查这两个错误C2913C3413。 这是你要找的吗?

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

      【讨论】:

      • 抱歉,意识到这不是@user438938 所要求的。误解了这个问题。
      猜你喜欢
      • 1970-01-01
      • 2018-07-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-11
      • 1970-01-01
      • 2021-01-14
      • 2021-12-18
      相关资源
      最近更新 更多