假设我有:
std::map<K, V1> m1;
std::multimap<K, V2> m2;
Run Code Online (Sandbox Code Playgroud)
我想按容器类型和键/值类型模板.但是以下不起作用:/
template <typename T>
void do_something(T var)
{
// do something
}
template <typename TContainer, typename TKey, typename TVal>
void func(const TContainer<TKey, TVal>& container)
{
for (typename TContainer<TKey, TVal>::iterator it = container.begin(); it != container.end(); ++it)
{
do_something(it->second);
}
}
Run Code Online (Sandbox Code Playgroud)
然后调用它:
func(m1);
func(m2);
Run Code Online (Sandbox Code Playgroud)
你不能只有一个模板参数吗?
template <typename Container>
void func(const Container & container)
{
for (typename Container::iterator it = container.begin(); it != container.end(); ++it)
{
do_something(it->second);
}
}
Run Code Online (Sandbox Code Playgroud)
或者更好的是,将迭代器传递给函数而不是容器:
template <typename ForwardIterator>
void func(ForwardIterator begin, ForwardIterator end)
{
for (; begin != end; ++begin)
{
do_something(begin->second);
}
}
Run Code Online (Sandbox Code Playgroud)
如果您真的需要模板模板参数,请参考以下语法:
template <template <typename, typename> Container, typename TKey, typename TValue>
void func(const Container<TKey, TValue> & container);
Run Code Online (Sandbox Code Playgroud)
但是,这对STL容器不起作用,因为它们通常具有比看起来更多的参数; 实际上,它们通常具有默认值的参数,例如allocator,所以最好的办法是使用上面描述的通用算法的惯用方法,即处理迭代器而不是容器.
这不起作用的原因是std::map需要四个模板参数:
template<class Key,
class Value,
class Predicate = std::less<Key>,
class Allocator = std::allocator<pair<const Key, Value> > >
class map;
Run Code Online (Sandbox Code Playgroud)
虽然您可以省略最后两个用于实例化的参数,但您必须列出它们才能使模板匹配起作用:
template < typename TKey,
typename TVal,
class TPr,
class TAl
template<typename,typename,class,class> TContainer >
void func(const TContainer<TKey, TVal, TPr, TAl>& container)
{
for (typename TContainer<TKey, TVal, TPr, TAl>::iterator it = container.begin(); it != container.end(); ++it)
{
do_something(it->second);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,我想知道你为什么要这么烦.惯用的方法是传递迭代器:
template <typename FwdIt>
void func(FwdIt begin, FwdIt end)
{
while(begin != end) {
do_something(begin->second);
++begin;
}
}
Run Code Online (Sandbox Code Playgroud)
这也允许您传递任何兼容的内容:
void f(const std::vector< std::pair<int, std::string> >& v)
{
func( v.begin(), v.end() );
}
Run Code Online (Sandbox Code Playgroud)