部分专业化语法混淆

时间:2012-02-17 05:49:20

标签: c++ templates

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

 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<void *>定义部分看起来像是我的父类。

  1. 为什么不在Vector <void *>中指定template <class T> class Vector <void *>
  2. 如果任何人可以细分定义部分,那就太棒了。 (对不起,如果要问太多话)

4 个答案:

答案 0 :(得分:2)

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

部分特化意味着您通过匹配更具限制性的模式,从现有的模板中创建一个更专业但仍然是通用的新模板。您的示例的一般模式是这样的:

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

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

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

第一行是主要模板,并匹配所有,而不是更专业的表单。第三行定义了一个实际的类型(不是模板!)Foo<fool>(对于某些给定类型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<void*>:事实证明,作者选择将部分专用的Vector<U*>定义为派生自固定类Vector<void*>(必须在其他地方完全专业化) )。

答案 1 :(得分:0)

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

这是专门用于指针类型T的Vector<T>的模板类定义。可能,您已在其他地方定义了Vector<T>模板,因此此代码仅针对其中的情况进行了专门化T是一个指针。因此Vector<T*>

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

答案 2 :(得分:0)

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

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

答案 3 :(得分:0)

似乎代码的作者想要利用不同指针类型的代码相同的事实。减少代码大小或“代码膨胀”可能只是一个不成熟的优化。这个想法很可能是每个新的指针类型只会向void指针代码添加一层static_cast。