如何从模板类创建具体类

时间:2014-09-11 07:01:34

标签: c++ templates concrete-inheritance

说我有一个模板类:

template <typename T> class StringDeque:
public std::deque<T>
{
public:

    ...

private:
    typedef std::deque<T> BaseClass; 
};

说我想创建具体的课程ArrayString,其中T=std::string。 实现这一目标的正确方法是什么:

定义

#define ArrayString StringDeque<string>

的typedef

typedef StringDeque < string > ArrayString;

继承

class ArrayString :
    public StringDeque < string > {};

我不确定所有建议是否有效。无论如何,我试图弄清楚哪种做法最适合。

3 个答案:

答案 0 :(得分:3)

您想为特定类型命名(恰好是模板的实例化)。给类型赋予名称(别名)的C ++方法是使用typedef:

typedef StringDeque<string> ArrayString;

或者,从C ++ 11开始,带有别名声明:

using ArrayString = StringDeque<string>;

旁注:在考虑这些内容时,通常会根据正确的模板术语进行思考。您没有“模板类”(具有特殊属性的),您有一个“类模板”(用于创建类的模板)。模板不是类型;它的实例化是。

答案 1 :(得分:2)

正确的方法:

typedef std::deque<std::string> StringDeque;
using StringDeque = std::deque<string>;

那就是说,这里有一些关于你问题的补充说明:

您写道:

template <typename T> class StringDeque: public std::deque<T> // ...

std容器类不是基类。这意味着它们不应该继承(并且从它们继承是UB)。

如果要在另一个类中使用std容器功能,答案应始终是封装。这意味着,在类中构建std :: queue功能的正确方法是:

template<typename T> class StringDequeue {
    std::deque<T> storage;
public:
    // add interface here that uses storage
};

您还建议:

#define ArrayString StringDeque<string>

请永远不要使用define来声明类型。它有效,但它有自己的陷阱,在C ++中被认为是不好的做法。

答案 2 :(得分:1)

使用typedef或(自C ++ 11开始)创建类型别名using

typedef StringDeque<std::string> ArrayString;
using ArrayString = StringDeque<std::string>;

预处理器是一个大锤:偶尔有用,但是在不了解语言级构造的情况下,容易以令人惊讶的方式破解代码。在这种情况下,我认为唯一的问题是名称不会被限制在任何范围内;但这个理由足以避免它。

继承创建一个新类型;虽然它通常可用于基类型,但它不是完全可互换的,并且不会从基类型继承任何构造函数。因此,对于简单类型别名,这也不是您想要的。