模板偏特化 - 有现实世界的例子吗?

4

我在思考偏特化。虽然我理解这个想法,但我还没有看到任何实际使用这种技术的例子。完全特化STL中被广泛使用,所以我对此没有问题。你能教育我一个使用偏特化的实际例子吗?如果这个例子在STL中那就更好了!


听起来像是作业;P - Aiden Bell
@Aiden 真的吗?!我不认为大学允许这些事情! - Khaled Alshaya
@Arak ... 我忘记了学院是全 Java 和 MSWord.. 对不起 ;) - Aiden Bell
@Aiden,现在你说出了真相:D - Khaled Alshaya
大学里没有人教我们 MS Word。:( - jalf
@jalf,高兴一下。我们的老师告诉我们如何使用鼠标最大化MS Word窗口。 - Johannes Schaub - litb
3个回答

13

C++0x引入了unique_ptr,这是auto_ptr的替代品,后者已经被弃用。

如果你将unique_ptr用于数组类型,则使用delete[]来释放内存,并提供operator[]等方法。如果你将其用于非数组类型,则使用delete。它需要部分模板特化来实现。

template<typename T>
struct my_unique_ptr { ... };

template<typename T>
struct my_unique_ptr<T[]> { ... };

另一个(虽然非常值得怀疑)使用的是标准库中的std::vector<bool, Allocator>。 bool特化使用空间优化将bool打包成单个位。

template<typename T, typename Allocator = std::allocator<T> >
struct vector { ... };

template<typename Allocator>
struct vector<bool, Allocator> { ... };

另一个用途是与std::iterator_traits<T>一起使用。迭代器需要定义嵌套的typedefs value_typereference和其他正确的类型(例如对于const迭代器,reference通常是T const&),以便算法可以使用它们进行工作。主模板依次使用迭代器类型的成员类型。

template<typename T>
struct iterator_traits { 
  typedef typename T::value_type value_type; 
  ...
};

对于指针来说,当然不能这样使用。对于它们有一个部分专门化的方法。

template<typename T>
struct iterator_traits<T*> {
  typedef T value_type;
  ...
};

第二点非常有趣...我不知道,这是标准的一部分还是编译器特定的? - DeusAduro
@DeusAduro,是的,这是标准要求。这是一个可能产生误解的常见例子,因为它使得vector<bool>不再符合容器要求。 - Johannes Schaub - litb
呵呵,好老的vector<bool>。糟糕的设计决策,但它确实说明了一些使用部分特化可能实现的事情。 - jalf

5
在一些STL实现中,像std::vectorstd::list这样的集合使用部分模板特化来减少为指针集合生成的代码量。
每个类型T的模板实例化都会创建新的代码。然而,指针类型实际上都是相同的,因此为每个类型生成新代码是浪费的。可以通过使用void指针实现指针集合的私有部分,然后在公共接口中将其转换为适当的类型来减少这种情况。这大大减少了指针集合生成的代码量。
我认为这在Effective STL中有涉及。

+1 的提示优化 T* (我也可以在自己的模板类中使用) - mmmmmmmm
哇,我不知道这个,但听起来很合理。C++在底层真的很酷......哦等等,它没有设计上的“引擎盖” :) - rubenvb

1

引用自MSDN(C++类模板的部分特化)

// partial_specialization_of_class_templates.cpp
template <class T> struct PTS {
   enum {
      IsPointer = 0,
      IsPointerToDataMember = 0
   };
};

template <class T> struct PTS<T*> {
   enum {
      IsPointer = 1,
      IsPointerToDataMember = 0
   };
};

template <class T, class U> struct PTS<T U::*> {
   enum {
      IsPointer = 0,
      IsPointerToDataMember = 1
   };
};

1
@Dwefy,我不会给你的帖子投反对票 :) 但我不是在问什么是偏特化。谢谢... - Khaled Alshaya
但它看起来是部分规范的良好示例,甚至更好。它将更多类型注入到单一模板中,使您可以选择要特化的内容。 - Dewfy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接