简体   繁体   中英

Deduce type in lambda parameter in C++11

I have a container which stores iterators to other containers as follows:

typedef int my_id;    //id
typedef std::set<my_id>  my_group_t;   //group containing ids
typedef typename  my_group_t::iterator  my_group_it_t;    //group iterator

std::pair < my_group_it_t, my_group_it_t >  pair_it_t;  //pair (generally begin,end)
typedef std::vector<  pair_it_t >  my_group_container_t;


my_group_container_t   my_group_container; // (FILL the Container and group with some values)
//print the values using lambdas

auto x = my_group_container.begin();   
auto y = my_group_container.end();

//x is iterator to the vector, similarly y. 

//note that x and y when dereferenced give the pairs of iterators
std::for_each (x, y, [](**xxxx**   pair) -> void {

          auto xx = x.first;    //get first iterator pair
          auto yy = x.second;  //get second iterator pair

      } 

What should be the type of pair ? xxxx . I know lambdas cannot be templated in C++11, but I am not sure how to use decltype here.

 //I can do this:
  for (; x!=y; ++x) {
    auto xx = x->first;
    auto yy = x->second;
    std::copy(xx,yy,std::ostream_itearator<..> (std::cout, "\n");
  }

Note that while the example uses concrete types, my actual use case is in template code, where the real types are not known.

If you want to be generic, you have several options:

  1. Use iterator traits on the type of x :

     std::for_each(x, y, [](std::iterator_traits<decltype(x)>::value_type pair) { ... }) 
  2. Use the return type of *x :

     std::for_each(x, y, [](decltype(*x) pair) { ... }) 
  3. Use the value type of the container (directly or deduced):

     std::for_each(x, y, [](my_group_container_t::value_type pair) { ... }) std::for_each(x, y, [](decltype(my_group_container)::value_type pair) { ... }) 
  4. In case you actually know the type (as in the example), you of course use it directly:

     std::for_each(x, y, [](pair_it_t pair) { ... }) 

In all the cases, you can decorate the type of pair with const and/or & as applicable. Note that in case 2, the type may very well be a reference already - forward (or better) operators are required to return actual references.

In the provided example, it is pair_it_t .

but from template, you can use std::iterator_traits<It>::value_type to retrieve the type.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM