1

假设我有一个模板类:

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 StringDeque < string > ArrayString;

遗产

class ArrayString :
    public StringDeque < string > {};

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

4

3 回答 3

3

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

typedef StringDeque<string> ArrayString;

或者,从 C++11 开始,使用别名声明:

using ArrayString = StringDeque<string>;

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

于 2014-09-11T07:06:55.263 回答
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++ 中被认为是不好的做法。

于 2014-09-11T07:52:47.243 回答
1

typedef使用or (C++11 起)创建类型别名using

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

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

继承创建一个新类型;虽然它通常可以在基类型所在的地方使用,但它不是完全可互换的,并且不会从基类型继承任何构造函数。所以这也不是你想要的简单类型别名。

于 2014-09-11T07:11:29.803 回答