开发者

Associative Container as Function Template Parameter

开发者 https://www.devze.com 2023-04-09 18:14 出处:网络
I would like to know how I would write a function that can 开发者_运维知识库accept as a parameter an associative container that itself accepts two or more template parameters. For example, if I want t

I would like to know how I would write a function that can 开发者_运维知识库accept as a parameter an associative container that itself accepts two or more template parameters. For example, if I want to write a function that works for std::map, I could write something like what is shown below.

template <class Map, class Key, class Value, class Compare, class Allocator>
void foo(Map<Key, Value, Compare, Allocator>& map);

However, this will not work for boost::unordered_map, since boost::unordered_map accepts five template parameters. I could accept the map as a single template parameter and use the traits that it should support in order to deduce the key and value types later, but for nested maps, the code becomes very verbose and difficult to maintain. Is there an easier way to write such a function but still have it work for any associative container that accepts any number of template parameters greater than or equal to two?

Please note that accepting iterators instead of containers as parameters will not suffice, because I need more information about the container on which the iterator operates than what the iterator can provide.

Thank you very much!


Why not just use the simple approach with a single template parameter:

template <typename C> void foo(const C & container)
{
  typedef typename C::key_type key_type;
  typedef typename C::mapped_type mapped_type;

  // etc.
}

You can add some member-type-checking typetraits is you want additional checks that those member types exist, but that might not give any additional benefit.

Alternatively, you could do some generic pattern matching, though only with classes, not functions:

 template <typename> struct AtLeastTwo;

 template <typename K, typename V, typename ...Args>
 struct AtLeastTo<K, V, Args...>
 {
   // now have types K and V
 };

 typedef std::unordered_map<int, Foo, MyHash> map_type;
 AtLeastTwo<map_type> m;
 // ...


A type does not convey information on whether it is an associative sequence, such is a semantic meaning. If you wan't to support all kinds of associative sequence, as per the standard interface, your best bet is to go with a single template parameter and use traits to introspect its key/value type and so on.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号