我可以简化以下模板吗?

时间:2015-07-01 08:39:12

标签: c++ templates

编辑:

感谢您的出色答案。我显然没有详细说明我的问题。我试图纠正这个:

我正在更新一些遗留代码,并且有几个具有以下模式的重载函数:

void foo (Int bla, const char* bla1, const char* bla2, ...);
void foo (Int bla, SomeCustomContainer);

现在,我们正在逐步淘汰自定义容器,而是使用std容器。自定义容器的签名是这样的,我可以在continainer上模板,重用代码,同时支持旧代码和新代码,直到遗留代码被逐步淘汰。

我的第一次尝试是:

template <typename ContainerT> void foo(int bla, ContainerT);

但编译器会发出错误,因为它与const char *签名上的模板化函数匹配。

基于StackOverflow的答案,我尝试了以下模板签名:

template <typename ValT, template <typename, typename = std::allocator<ValT> >
          class ContainerT>
void foo(Int bla, const ContainerT<ValT>& rasInParams)

这解决了我的问题 - 编译器找到正确的重载并且一切正常用于我的目的。我唯一的抱怨是要解析一个对模板不太熟悉的同事,并且我想知道是否有一种简化方法的方法 - 我正在考虑类型别名,但也许有人知道更好的方法来解决我的潜在重载解决问题?

2 个答案:

答案 0 :(得分:2)

样本一般不起作用(想象一个不占用分配器的容器,或者需要两个以上的类型参数,或者上帝禁止非类型参数)。

我通常的做法只是

template <typename Container>
void foo(const ContainerT& rasInParams)

如果你需要知道值类型,你可以做任何事情,比如

typename Container::value_type

std::remove_reference<decltype(*rasInParams.begin())>::type

如果您确实需要从模板模板参数中嵌入可配置容器,则可以为嵌套容器使用可变参数签名:

template<typename ValT, template<T...> class Container>
void foo() {
    Container<ValT, std::allocator<ValT> > x;
}

另一个选择是使用容器&#34;选择器&#34;元功能。这是例如在Boost Graph库中使用:

答案 1 :(得分:1)

您可以简单地编写(假设您使用标准容器作为参数):

template <typename ContainerT>
void foo(const ContainerT& rasInParams) {
    using ValT = typename ContainerT::value_type;
    // ...
}

如果您希望foo在参数不是容器时不参与重载解析,则可以使用SFINAE。这看起来仍然比原始代码简单:

template <typename ContainerT, typename = ContainerT::value_type>
void foo(const ContainerT& rasInParams)