说我有一个模板类:
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 > {};
我不确定所有建议是否有效。无论如何,我试图弄清楚哪种做法最适合。
答案 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>;
预处理器是一个大锤:偶尔有用,但是在不了解语言级构造的情况下,容易以令人惊讶的方式破解代码。在这种情况下,我认为唯一的问题是名称不会被限制在任何范围内;但这个理由足以避免它。
继承创建一个新类型;虽然它通常可用于基类型,但它不是完全可互换的,并且不会从基类型继承任何构造函数。因此,对于简单类型别名,这也不是您想要的。