部分特化语法混乱

发布于 2025-01-06 02:09:20 字数 741 浏览 2 评论 0原文

定义用于每个指针向量且仅用于 指针向量,我们需要部分专业化:

 template <class T> class  Vector <T *> : private Vector<void *> {
 public:
      typedef Vector<void*> Base;
      Vector(): Base() {}
      explicit Vector(int i) : Base(i ) {}
      T *& elem(int i ) { return static_cast <T *&> (Base::elem(i)); }
      T *& opeator[](int  i) { return static_cast <T *&>(Base::operator[](i )); }
      //...
 };

这个定义让我感到头晕。这与部分专业化有关,但我不明白语法。 private Vector 定义部分对我来说看起来像父类。

  1. 为什么不在template中指定Vector类 Vector
  2. 如果有人能分解定义部分,那就太好了。 (抱歉,如果要求太多)

To define a specialization that is used for every Vector of pointers and only for
Vectors of pointers, we need a partial specialization:

 template <class T> class  Vector <T *> : private Vector<void *> {
 public:
      typedef Vector<void*> Base;
      Vector(): Base() {}
      explicit Vector(int i) : Base(i ) {}
      T *& elem(int i ) { return static_cast <T *&> (Base::elem(i)); }
      T *& opeator[](int  i) { return static_cast <T *&>(Base::operator[](i )); }
      //...
 };

This definition has me in a tizzy. This is related to partial specialization but i don't understand the syntax. private Vector<void *> definition part looks like a parent class to me.

  1. Why not specify Vector <void *> in template <class T> class Vector <void *>.
  2. It would be great if anybody can breakdown the definition part. (sorry if its too much to ask)

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

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

发布评论

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

评论(4

国粹 2025-01-13 02:09:20

忘记继承,这与手头的问题无关。

部分专业化意味着您通过匹配更严格的模式,从现有模板中创建一个更专业但仍然通用的新模板。您的示例的一般模式如下:

template <typename T> class Foo;      // primary template

template <typename U> class Foo<U*>;  // partial specialization

template <> class Foo<fool>;          // full specialization

第一行是主模板,匹配与更专业的表单不匹配的所有内容。第三行定义了一个实际的类型(不是模板!)Foo(对于某些给定的类型fool)。另一方面,中间的一行仍然是一个模板,但它只匹配 T = U * 形式的类型,即指针:

 Foo<char> x;   // uses primary template with T = char
 Foo<fool> y;   // uses full specialization (nothing to be matched)
 Foo<int*> z;   // uses partial specialization, matching U = int

关于 Vector:事实证明,作者选择将部分特化的 Vector 定义为派生自固定类 Vector >(这会必须在其他地方完全专业化)。

Forget about the inheritance, which has nothing to do with the problem at hand.

Partial specialization means that you make a new template from an existing one which is more specialized, but still generic, by matching a more restrictive pattern. The general pattern of your example is like this:

template <typename T> class Foo;      // primary template

template <typename U> class Foo<U*>;  // partial specialization

template <> class Foo<fool>;          // full specialization

The first line is the primary template and matches everything that is not matched by a more specialized form. The third line defines an actual type (not a template!) Foo<fool> (for some given type fool). The middle line, on the other hand, is still a template, but it only matches a type of the form T = U *, i.e. a pointer:

 Foo<char> x;   // uses primary template with T = char
 Foo<fool> y;   // uses full specialization (nothing to be matched)
 Foo<int*> z;   // uses partial specialization, matching U = int

About the Vector<void*>: It just turns out that the author chooses to define the partially-specialized Vector<U*> as deriving from a fixed class Vector<void*> (which would have to be fully specialized elsewhere).

是你 2025-01-13 02:09:20

您的问题是关于模板专业化,这就是这里发生的事情。

这是专门用于指针类型 T 的 Vector 模板类定义。大概,您已在其他地方定义了 Vector 模板,因此此代码仅针对 T 是指针的情况对其进行专门化。因此就有了Vector

由于它是一种特化,Vector 派生自 Vector 'base-template',它是一个 Vector。其他代码(在您的示例中未详细说明)将处理使用指针类型作为所包含数据的细节。

Your question is about template specialization, and that's what's going on here.

This is a template class definition of a Vector<T> being specialized for a pointer type T. Presumably, you've defined the Vector<T> template elsewhere, so this code is only specializing it for the circumstance where T is a pointer. Hence the Vector<T*>.

Since it is a specialization, the Vector<T*> derives from the Vector 'base-template', which is a Vector<void *>. The other code, which isn't detailed in your example, would handle specifics of working with a pointer type as the contained data.

栖竹 2025-01-13 02:09:20

基本上,对于任何指针类型,这使得 Vector 的成员转发到 Vector (使用继承和显式基调用的组合)加上铸造)。 可以防止编译器生成相同代码的许多相同版本,仅指针类型不同,可能会节省最终可执行文件中的空间(尽管大多数链接器足够聪明,可以组合相同的函数,例如参见“COMDAT 折叠”)

这 根据标准,这是有问题的,因为指针没有相同的对齐限制。在一致的实现中,并非所有对象指针都必须具有相同的大小。事实上,我非常惊讶编译器竟然接受 static_cast(a_void_ptr) 。当然,允许 void*T* 之间的静态转换,但这涉及到不相关的指针引用类型。它应该需要reinterpret_cast

Basically, this is making the members of Vector<Ptr>, for any pointer type, forward to Vector<void*> (using a combination of inheritance and explicit base calls plus casting). This prevents the compiler from making many identical versions of the same code, differing only by the pointer type, possibly saving space in the final executable (although most linkers are smart enough to combine identical functions, see for instance "COMDAT folding")

This is problematic according to the Standard because the pointers don't have the same alignment restrictions. Not all object pointers necessarily have the same size in a conforming implementation. In fact, I'm very surprised that the compiler accepts static_cast<T*&>(a_void_ptr) at all. Static casting between void* and T* is allowed of course, but this deals with reference-to-pointer types, which are unrelated. It should require reinterpret_cast.

她如夕阳 2025-01-13 02:09:20

代码的作者似乎想利用不同指针类型的代码是相同的这一事实。这可能只是为了减少代码大小或“代码膨胀”而进行的过早优化。这个想法很可能是每个新的指针类型只会在 void 指针代码中添加一层 static_cast 。

It seems that the author of the code wants to exploit the fact that the code for different pointer types is identical. It is probably just a premature optimization to reduce code size, or "code bloat". The idea is most likely that each new pointer type will only add a layer of static_cast to the void pointer code.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文