首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >模板专业化

模板专业化
EN

Stack Overflow用户
提问于 2014-10-07 19:21:33
回答 2查看 101关注 0票数 0

我正在阅读Addison的“C++模板:完整指南”一书,并有一个关于类模板的专门化的问题。我理解它是如何工作的,但是我很难理解您何时会从给定的示例中使用这个特性。下面是Stack类的一般定义:

代码语言:javascript
复制
#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(); 
    } 
}; 

这是专业知识

代码语言:javascript
复制
#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知道应该包含哪一个定义?在我看来,您最好在这个场景中实现两个不同的类,一个是通用堆栈类,另一个是专门的StackString类。

有什么想法?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2014-10-07 19:29:08

客户端是否需要知道有两个定义,可能存在于不同的头文件中,然后根据Stack类的类型T知道应该包含哪一个定义?

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

代码语言:javascript
复制
// 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>为例。)

票数 1
EN

Stack Overflow用户

发布于 2014-10-07 20:17:21

专门化类只与非专用变量共享基本名称,实际上您必须完全重写接口和实现,不能重用以前的代码。

最流行的专业是std::vector<bool>bool类型需要一个字节,但实际上一个字节可以存储8个bools。当您需要一个bools数组时,为了减少内存消耗,将更多的bools打包在一个字节中似乎是合理的。这里的专门化允许精确地实现这一点。

对于用户来说,一切都是透明的:您使用的vector<bool>vector<int>完全一样,但是第二个依赖于一个动态的in数组,而第一个则以完全不同的方式处理比特。

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

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26243586

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档