Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to declare the value of an iterator through decltype

In C++98, I typically use the following to declare a variable in an iterator's value type:

typename std::iterator_traits<Iterator>::value_type value;

In C++11 we have decltype and I had thought the easiest way to deduce the value type is:

decltype(*iterator) value;

Unfortunately for most iterators, the type of *iterator is value_type& and not value_type. Any ideas, without the type modification classes, how to massage the above into yielding the value_type (and not any reference)?


I don't think the question is unreasonable given that the following is fairly robust but ends up creating another variable.

auto x = *iterator;
decltype(x) value;

Also note that I really want the deduced type and not just an instance e.g. if I wanted to declare a std::vector of these values.

like image 714
Glen Low Avatar asked Mar 22 '13 00:03

Glen Low


1 Answers

Keep using iterator_traits. decltype(*iterator) could even be some sort of weird proxy class in order to do special things in the expression *iter = something.

Example:

#include <iostream>
#include <iterator>
#include <typeinfo>
#include <vector>

template <typename T>
void print_type()
{
    std::cout << typeid(T).name() << std::endl;
}

template <typename Iterator>
void test(Iterator iter)
{
    typedef typename
        std::iterator_traits<Iterator>::value_type iter_traits_value;

    auto x = *iter;
    typedef decltype(x) custom_value;

    print_type<iter_traits_value>();
    print_type<custom_value>();
}

int main()
{
    std::vector<int> a;
    std::vector<bool> b;

    test(a.begin());
    test(b.begin());
}

Output on MSVC 2012:

int
int
bool
class std::_Vb_reference<struct std::_Wrap_alloc<class std::allocator<unsigned int>>>

They aren't the same.

like image 78
aschepler Avatar answered Oct 27 '22 00:10

aschepler