Reputation: 4497
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.
Upvotes: 8
Views: 4331
Reputation: 163
For this use-case i like std::decay. Typicall i'd be using
std::vector< int > vec;
using value_type = typename std::decay< decltype(*begin(vec)) >::type;
static_assert(std::is_same< int, value_type >::value, "expected int");
Upvotes: 1
Reputation: 72336
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.
Upvotes: 16