3

如何通过 typedef 区分模板参数?

情况:我有几种类型的列表(实现为向量)。我有一个特殊的 StringList,我想以不同的方式处理它。

typedef std::vector<std::string> StringList;

inline void f(StringList const& list) {
  ...
}

template <typenamte T>
inline void f(std::vector<T> const& list) {
  ...
}

在定义我的变量的情况下,我StringList希望调用第一个版本,当定义变量时,std::vector<std::string>我希望调用第二个版本。但是StringListstd::vector<std::string>调用第一个版本。使用using给出相同的行为。

如果这不是可能的,那么一个合理的解决方法的想法会很好。

当然扩展std::vector<std::string>会有所帮助,但由于这根本不是一个好主意,我不知道如何区分它们。

4

2 回答 2

4

你至少有三个选择:

#include <vector>
#include <string>

// option 1

struct StringList : std::vector<std::string>
{
    // optionally forward the constructors of std::vector that are called
};

// option 2

struct String : std::string
{
    // optionally forward the constructors of std::string that are called
};

typedef std::vector<String> StringList;

// option 3

struct StringTag
{
};

typedef std::allocator<StringTag> StringAllocator;

typedef std::vector<std::string, StringAllocator> StringList;

第一个和第二个选项都需要转发基类的一些构造函数。std::string第二个选项可能更好,基于在将字符串添加到字符串列表时可能只需要转发复制构造函数的假设。

第三个选项是我最喜欢的——部分是因为它是一种偷偷摸摸的 hack,但也因为它不需要继承或转发。它之所以有效,是因为容器T中分配器模板参数的参数std从未使用过。

编辑:C++ 标准意味着分配器value_type必须与value_type容器匹配 - 因此,如果您的标准库实现允许,您只能使用第三个选项。如果没有,我会推荐第一个或第二个选项。

编辑 2:另请参阅:如果标准容器元素类型和 std::allocator 类型不同,是不是错了?

于 2013-07-30T11:30:54.540 回答
1

好的,这是解决您问题的快速而肮脏的解决方案:

struct StringList : std::vector<std::string>
{};

现在您的函数将被正确调用。我不推荐它,但是没有更多信息很难给出更好的答案。另外,请阅读从 C++ STL 容器派生是否有任何真正的风险?了解所涉及的风险和问题。但是,就像我在评论中所说的那样,我建议将它们包装在类中。

于 2013-07-30T11:23:35.943 回答