模板类型推导:通过typedef区分

时间:2013-07-30 10:01:40

标签: c++ templates typedef

如何通过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) {
  ...
}

如果我的变量被定义为al StringList,我希望调用第一个版本,当变量定义为std::vector<std::string>时,我希望调用第二个版本。但StringListstd::vector<std::string>会调用第一个版本。使用using会产生相同的行为。

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

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

2 个答案:

答案 0 :(得分: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复制构造函数。

第三个选项是我最喜欢的 - 部分是因为它是一个偷偷摸摸的黑客,但也因为它不需要继承或转发。它的工作原理是因为T容器中的allocator template-argument的std参数永远不会被使用。

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

编辑2 :另请参阅:Is it wrong if the standard container element type and std::allocator type are different?

答案 1 :(得分:1)

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

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

现在您的函数将被正确调用。 我不推荐它,但没有任何信息,很难给出更好的答案。另外,请阅读Is there any real risk to deriving from the C++ STL containers?以了解所涉及的风险和问题。但是,就像我在评论中所说的那样,我建议将它们包装在课堂中。