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

发布于 2024-09-17 18:00:38 字数 603 浏览 10 评论 0原文

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

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’必须在使用之前声明”。 如果我尝试在注释行中提供前向声明,编译器会抱怨 “必须在包含模板的命名空间中声明显式专业化“B”。” 我们在这里使用 2 个不同的编译器。此错误来自 AIX 上的 IBM“xl”编译器,但在我们的 Sun 系统上编译时,我遇到了类似的错误,但措辞不同。 这似乎是第 22 条军规。

显然,这是一个精心设计、简单化的例子,但它代表了问题。 我想在类中定义模板类,因为模板类仅与包含类相关。不应从类外部访问该模板。

我错过了什么吗?

I can't get this to compile at all. I may not be possible but I don't know why it should not be.

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

As it appears the compiler complains "The explicit specialization "class A::B" must be declared before it is used."
If I try to provide the froward declaration in the commented line, the compiler complains
"The explicit specialization "B" must be declared in the namespace containing the template."
We use 2 different compilers here. This error is from IBM's "xl" compiler on AIX but I get similar errors with different verbage when compiling on our Sun systems.
It seems like a catch-22.

Obviously, this is a highly contrived, simplistic example but, it represents the problem.
I want to define a template class within a class because the template class is only relevent to the containing class. There should be no access to the template from outside the class.

Am I missing something?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

我很OK 2024-09-24 18:00:38

你是对的。这是不可能做到的(据我所知)。您的成员声明会在声明显式专业化之前导致隐式实例化。但你想如何声明呢?你不能在类范围内这样做。其他人则认为这是一个丑陋的限制

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

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

You are correct. This is not possible to do (as far as I know). Your member declaration causes an implicit instantiation before the explicit specialization was declared. But how would you want to declare it? You cannot do that in class scope. Others have felt that this is an ugly restriction.

You could work around this by making the class member a pointer. This would not need to implicitly instantiate the class at that point, but rather at the point where you create the object in the end. I realize that this is an ugly work around. So better find other ways to do this.

For instance partial specializations are allowed in class scope. So you could add a dummy template parameter, then you can specialize this in the class before the member declaration. Likewise, i find this ugly, but it would not disturb things that much, I feel.

哽咽笑 2024-09-24 18:00:38

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

namespace {

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

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

}

class A {
  B<int> myB_;
};

这将编译,但如果 A 需要在此编译单元之外可见,您将需要更复杂的机制(例如< /em>、接口和工厂或 Pimpl)。

You could work around the issue by using an unnamed namespace for privacy:

namespace {

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

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

}

class A {
  B<int> myB_;
};

This will compile, but if A needs to be visible outside this compilation unit, you'll need more elaborate machinery (e.g., interface and factory or Pimpl).

私野 2024-09-24 18:00:38

B 不是模板类,您正在尝试对其进行专门化。这就是错误的原因。您可以检查这两个错误 C2913 和 < a href="http://msdn.microsoft.com/en-us/library/t72c30ht(VS.80).aspx" rel="nofollow noreferrer">C3413。
这是您要找的吗?

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

B is not a template class and you are trying to specialize it. That is the cause for the error. You can check these two errors C2913 and C3413.
Is this what you are looking for?

class A
{
   template<class T>
   class B
   {
      inline int test()
      {
         return 0;
      }
   };
   A::B<int> myB_;
};
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文