繁体   English   中英

模板专长

[英]Template specializations

我正在阅读Addison Wesley撰写的《 C ++模板:完整指南》一书,对类模板的专业化有疑问。 我了解它是如何工作的,但是我无法从给定的示例中了解何时使用此功能。 这是Stack类的一般定义:

#include <vector> 
#include <stdexcept> 

template <typename T> 
class Stack { 
  private: 
    std::vector<T> elems;     // elements 

  public: 
    void push(T const&);      // push element 
    void pop();               // pop element 
    T top() const;            // return top element 
    bool empty() const {      // return whether the stack is empty 
        return elems.empty(); 
    } 
}; 

这是专业化

#include <deque> 
#include <string> 
#include <stdexcept> 
#include "stack1.hpp" 

template<> 
class Stack<std::string> { 
  private: 
    std::deque<std::string> elems;  // elements 

  public: 
    void push(std::string const&);  // push element 
    void pop();                     // pop element 
    std::string top() const;        // return top element 
    bool empty() const {            // return whether the stack is empty 
        return elems.empty(); 
    } 
}; 

我的问题是,它似乎违反了有关封装的OOP原则。 客户是否需要知道有两个定义(可能位于不同的头文件中),然后根据赋予Stack类的类型T知道要包含哪个定义? 在我看来,在这种情况下仅实现两个不同的类(一个通用的Stack类和一个专门的StackString类)会更好。

思考?

客户是否需要知道有两个定义(可能位于不同的头文件中),然后根据赋予Stack类的类型T知道要包含哪个定义?

绝对没有必要将它们放入两个不同的打开的头文件中,即库用户将看到和使用的头文件。 它们可能在内部组织为两个不同的实现标头,然后包含在用户将看到并包含的主要标头中。 但是,用户既不知道一个明确的分工,也不是说他是一个。

// Stack.impl.hpp

// primary template:
template <typename T>
class Stack {
   // [...]
};

// Stack_StringSpec.impl.hpp

#include "Stack.impl.hpp"
// explicit specialization:
template <>
class Stack<std::string> {
   // [...]
};

// Stack.hpp

#include "Stack.impl.hpp" // Included for clarity
#include "Stack_StringSpec.impl.hpp"

请注意,在大多数情况下,由于用户应该/需要知道的原因,专业化仍然会被记录下来,因为它肯定存在。 (以std::vector<bool>为例。)

专门的类仅与未专门化的变体共享基本名称,实际上您必须完全重写接口和实现,没有任何以前的代码可以重用。

最受欢迎的专业是std::vector<bool> bool类型需要1个字节,但实际上一个字节可以存储8个bool 当您需要布尔数组时,为了减少内存消耗,将更多的布尔数组打包在一个字节中似乎是合理的。 这里的专业化可以实现这一点。

对用户而言,所有事情都是透明的:您使用vector<bool>vector<int> vector<bool>完全相同,但是第二个依赖于整数的动态数组,而第一个则以完全不同的方式使用位。

专业化不必一定在同一标头中,但是当用户包括该类时,应该使所有专业化可见,否则您可能会无法使用它们(您不想记住要包括使用vector<bool>时的另一个文件)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM