有没有办法让这样的工作:
template<typename T, typename X, typename Y>
void myFunc(T<X,Y> map, X x, Y y) {
map[x] += y;
}
基本上我希望任何类似map<X,Y>
的内容都是有效的输入。
这可能吗?
我收到此错误但我不知道这意味着什么:
test.cpp:2:17:错误:'T'不是模板
答案 0 :(得分:4)
是,使用模板模板模板参数:
template <template <typename, typename> class M, typename K, typename V>
void Foo(M<K, V> & container)
{
// ...
};
请注意,这永远不会匹配任何真实单词容器,因为它们有更多的模板参数。可变参数更好:
template <template <typename, typename, typename...> class M, typename K, typename V, typename ...Args>
void Foo(M<K, V, Args...> & container)
{
// ...
};
如果variadics不是一个选项,你可以自己利用一些包装:
template <typename Container> void FooImpl(Container &);
template <template <typename, typename> class M,
typename K, typename V>
void Foo(M<K,V> & c) { FooImpl(c); }
template <template <typename, typename, typename> class M,
typename K, typename V, typename A1>
void Foo(M<K,V,A1> & c) { FooImpl(c); }
template <template <typename, typename, typename, typename> class M,
typename K, typename V, typename A1, typename A2>
void Foo(M<K,V,A1,A2> & c) { FooImpl(c); }
// etc.
作为参考,std::unordered_map
需要五个模板参数(键,值,散列函数,等式谓词,分配器)。提升的bimap
可能需要更多。
通过使函数成为包装类的静态成员并使实现变为私有,并通过提供单个免费访问器辅助函数,可以防止滥用此最后一个结构。
答案 1 :(得分:3)
最简单的方法是仅使用T
作为参数类型。
template<typename T, typename X, typename Y>
void myFunc(T map, X x, Y y) {
map[x] += y;
}
请注意,这将允许例如。数组为T
s(例如。T = int*, X = int, Y = int
,该函数会将y
添加到数组x
的{{1}}元素。
如果你想将它缩小到地图,你必须根据你决定是一张地图。识别地图的一种可能性是检查他们的map
和key_type
。例如:
mapped_type
如果你真的想接受任何带有两个类型参数(而不是更多)的东西,你可以使用模板模板参数。但是,我认为这是一种过于语法的区别,除非您打算使用多个参数类型实例化template-template参数,否则不应该使用它。
答案 2 :(得分:1)
如果你没有将map约束为T类,事情会变得简单得多:
template<typename T, typename X, typename Y>
void myFunc(T map, X x, Y y) {
map[x] += y;
}
// ...
map<int, int> myMap;
myFunc(myMap, 5, 7);
std :: map实际上有比K和V更多的参数(它还有一个比较器和一个分配器),所以最好不要匹配它的模板参数。上面的代码仍然只编译那些有非const运算符[]的东西,以X作为键并返回Y作为值,但它对于非特定容器的容器也是灵活的,例如Container