我有一个模板函数,它将容器作为参数 (我将此函数用于矢量,集合,映射,因此试图避免它会花费大量代码复制) 所以我很自然地宣称:
template<template<class T, class Allocator = std::allocator<T>> class
Container> Container<std::weak_ptr<A>>* Foo() {...}
请注意,Foo
的返回值使用容器的默认参数。
当我使用带向量的函数时,列出或设置它可以正常工作;
我遇到的问题是当我尝试将此模板与比较器和值类型固定的地图容器一起使用时(定义为MapToValue<ValueType>::FromKey
且A
已定义Comparator<Key>
):< / p>
template<class Value> class MapToValue {
template<class Key, class Allocator = std::allocator<std::pair<const
Key, Value>>> FromKey : public std::map<Key, Value, Comparator<Key>,
Allocator> {...}
在这种情况下,分配器的默认值与Foo
- std::allocator<std::pair<_Ty, std::string>>
与std::allocator<_Ty>
的定义中的默认值不同。
长话短说,我需要发送到Foo
一个容器,其中第二个参数可以默认,不知道这个默认类型是什么(所以这个函数模板可以用于map,vector或者基本上任何其他容器)。这可能吗?
答案 0 :(得分:0)
在c ++ 11中,您可以将任何模板作为模板参数:
North
答案 1 :(得分:0)
这里有一个关于模板模板参数如何运作的误解。这个声明:
template<template<class T, class Allocator = std::allocator<T>> class Container>
Container<std::weak_ptr<A>>* Foo() {...}
只是这个宣言的过于冗长的版本:
template < template <class, class> class Container>
Container<std::weak_ptr<A>>* Foo() {...}
(什么是A
btw?)
Container
所采用的类型的名称或默认值无关紧要 - Foo
只是在某个带有两个模板类型参数的类模板上进行模板化。这与vector
一起使用,因为它是一个带有两个模板类型参数的类模板:
template<
class T,
class Allocator = std::allocator<T>
> class vector;
它不适用于map
,因为它需要四个模板类型参数:
template<
class Key,
class T,
class Compare = std::less<Key>,
class Allocator = std::allocator<std::pair<const Key, T> >
> class map;
在C ++ 11中,您可以将函数概括为使模板模板参数采用任意数量的模板类型参数:
template < template <class...> class Container>
Container<std::weak_ptr<A>>* Foo() {...}
但是,由于某些容器类型不能仅使用单个模板参数(例如map
)构建,因此它永远不会起作用。
答案 2 :(得分:0)
我找到了一个解决方案,它并不优雅,但它有效:
发送给Foo
另一个模板参数,该参数可以解决分配器:
template<template<typename> class DefaultAllocator, template<typename T,
typename Allocator = DefaultAllocator<T>> class Container>
Container<std::weak_ptr<A>>* Foo() {...}
这样我发送Foo<std::allocator,std::vector>
全部相同。
另外,通过创建一些包装器template<class T> class MapAllocatorWrapper : std::allocator<std::pair<T,std::string>>
,我可以在稍作调整后发送Foo<MapAllocatorWrapper, MapToType<std::string>::FromKey
。