编辑:
感谢您的出色答案。我显然没有详细说明我的问题。我试图纠正这个:
我正在更新一些遗留代码,并且有几个具有以下模式的重载函数:
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)
这解决了我的问题 - 编译器找到正确的重载并且一切正常用于我的目的。我唯一的抱怨是要解析一个对模板不太熟悉的同事,并且我想知道是否有一种简化方法的方法 - 我正在考虑类型别名,但也许有人知道更好的方法来解决我的潜在重载解决问题?
答案 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)