简体   繁体   中英

Finding the value type of an Iterator

I have a template parameter InIter in one of my overloaded functions, and I need to call a for_each_n to loop with InIter for x iterations, which I don't have any trouble doing. But I'm having trouble getting the value type of the iterator, to give an example:

//invalid lambda function
for_each_n(param1, param2, param3,
    [val](InIter it) {
        *it = val;
    });

this however does not work, I need to pass in the value type of InIter it rather than the entire iterator. This example does work below, but obviously I can't just leave the type std::size_t or I'll be forced to create only std::size_t containers.

for_each_n(param1, param2, param3,
    [val](std::size_t& v){
        v = val;
    });

How to do it..

To get the value-type of an iterator you should use std::iterator_traits from <iterator> , this will make it very easy to obtained the wrapped value_type , as well as being generic enough so that you can even use it with pointers .

std::iterator_traits<InIter>::value_type
std::iterator_traits<char       *>::value_type                     => char
std::iterator_traits<char const *>::value_type                     => char const
std::iterator_traits<std::vector<int>::iterator      >::value_type => int
std::iterator_traits<std::vector<int>::const_iterator>::value_type => int const

Alternative

If you are writing C++11 , and have an instance of InIter , there's also the posibility of using decltype to obtain the type of *it , which effectively (in most/all cases) is the same as what std::iterator_traits<T>::value would yield.


Implementation

Judging from your example snippets it seems that you, instead of wanting the value_type of the iterator, are more interested in the actual reference-type , below is a sample implementation:

for_each_n(param1, param2, param3,
  [val](typename std::iterator_traits<InIter>::reference v){
    v = val;
  }
);
for_each_n(param1, param2, param3, [val](decltype(*some_it) v){
  v = val;
});

Use std::iterator_traits . You can use std::iterator_traits<InIter>::value_type to reference the value type of the iterator. This will work for both custom iterators and pointers, because of the template specializations. So if InIter is T* or const T* for some T , you will get the correct value type.

Custom iterators define a value_type member type directly, but when writing code that can handle any type of iterator it's not safe to use InIter::value_type to reference the value type of the iterator because InIter might be just a pointer, which has no value_type member 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