Template function map / multimap in C ++

Suppose I have:

std::map<K, V1> m1;
std::multimap<K, V2> m2;

I would like to create a template by container type and by type / value. However, the following does not work: /

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);
  }
}

And then name it with:

func(m1);
func(m2);
+3
source share
5 answers

You can not have only one template parameter?

template <typename Container>
void func(const Container & container)
{
    for (typename Container::iterator it = container.begin(); it != container.end(); ++it)
    {
        do_something(it->second);
    }
}

Or better, pass iterators to your function instead of the container:

template <typename ForwardIterator>
void func(ForwardIterator begin, ForwardIterator end)
{
    for (; begin != end; ++begin)
    {
        do_something(begin->second);
    }
}

If you really need a template template parameter, here is the syntax:

template <template <typename, typename> Container, typename TKey, typename TValue>
void func(const Container<TKey, TValue> & container);

STL, , ; , , , , , .. .

+7

, , , std::map :

template<class Key,
         class Value,
         class Predicate = std::less<Key>,
         class Allocator = std::allocator<pair<const Key, Value> > >
class map;

, :

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);
  }
}

, , . :

template <typename FwdIt>
void func(FwdIt begin, FwdIt end)
{
  while(begin != end) {
    do_something(begin->second);
    ++begin;
  }
}

, :

void f(const std::vector< std::pair<int, std::string> >& v)
{
   func( v.begin(), v.end() );
}
+7

, , , Boost.Range:

#include <boost/range.hpp>

template<typename ForwardReadableRange>
void func(const ForwardReadableRange& range) {
  typedef typename boost::range_iterator<const ForwardReadableRange>::type InputIterator;
  for (InputIterator it = boost::begin(range); it != boost::end(range); ++it) {
    do_something(it->second);
  }
}

template<typename ForwardReadableWriteableRange>
void func(ForwardReadableWriteableRange& range) {
  typedef typename boost::range_iterator<ForwardReadableWriteableRange>::type ForwardIterator;
  for (ForwardIterator it = boost::begin(range); it != boost::end(range); ++it) {
    do_something(it->second);
  }
}

, ForwardReadable(Writeable)Range, . .

, DoSomethingWithSecond for_each:

template<typename T, typename UnaryOp, typename Result>
struct DoSomethingWithSecond: std::unary_function<T, Result> {
  UnaryOp op;
  explicit DoSomethingWithSecond(UnaryOp op): op(op) { }
  Result operator()(T value) {
    return op(value.second);
  }
};
template<typename T>
void func(T range) {
  boost::for_each(range, DoSomethingWithSecond(do_something));
}
+1

, , ( , ), , . " ", "", " " " ".

template <typename T>
void do_something(T var)  // Also consider "const T&"
{
  // do something
} 

template <typename TContainer>
void func(const TContainer& container)
{
  for (typename TContainer::iterator it = container.begin();
       it != container.end(); ++it)
  {
    do_something(it->second);
  }
}
0

. , . , :

#include <algorithm>
#include <functional>

// This should be part of the standard, but it isn't.
template <typename Func1, typename Func2>
struct composer :
    std::unary_function
        <
            typename Func2::argument_type,
            typename Func1::result_type
        >
{
    composer(Func1 f1_ = Func1(), Func2 f2_ = Func2())
        : f1(f1_), f2(f2_)
    {}

    typename Func1::result_type 
    operator()(typename Func2::argument_type x)
    { return f1(f2(x)); }

private:
    Func1 f1; Func2 f2;
};


template <typename F1, typename F2>
composer<F1, F2> compose(F1 f1, F2 f2)
{ return composer<F1, F2>(f1, f2); }


template <class C, typename T, T C::*ptr>
struct mem_ptr : std::unary_function<C&, T&>
{ T& operator()(C& x) { return x::*ptr; } };


template <typename Iter>
void func(Iter begin, Iter end)
{
    typedef typename Iter::value_type pair_t;

    typedef mem_ptr
    <
        pair_t,
        pair_t::second_type,
        pair_t::&second
    > second_of;

    std::for_each(begin, end, compose(ptr_fun(do_something), ptr_mem));
}

compose mem_ptr , ( TR1, ). , do_something, do_something .

, ptr_mem ,

ptr_mem(pair_t::&second)

. Boost , 20- .

0

Source: https://habr.com/ru/post/1753704/


All Articles