Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why can't I get value_type from iterator_traits?

I'm doing this:

const int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 };
const auto foo = cbegin(arr);
const typename iterator_traits<decltype(foo)>::value_type bar = 1;

I would have expected bar to have the type int. But instead I'm getting an error:

error C2039: value_type: is not a member of std::iterator_traits<_Ty *const >

Is this a problem with the const do I need to strip that or something?

like image 395
Jonathan Mee Avatar asked Jan 09 '19 15:01

Jonathan Mee


People also ask

What is difference_ type c++?

difference_type - a type that can be used to identify distance between iterators. value_type - the type of the values that can be obtained by dereferencing the iterator. This type is void for output iterators.

What is iterator_ traits?

iterator_traits are used within algorithms to create local variables of either the type pointed to by the iterator or of the iterator's distance type. The traits also improve the efficiency of algorithms by making use of knowledge about basic iterator categories provided by the iterator_category member.

Is iterator type trait?

std::iterator_traits is the type trait class that provides uniform interface to the properties of LegacyIterator types. This makes it possible to implement algorithms only in terms of iterators.


2 Answers

The issue here is with the line

const auto foo = cbegin(arr);

cbegin(arr) is going to return a int const * (pointer to const int) so applying const to that with const auto foo means foo is a int const * const (const pointer to const int)

std::iterator_traits is only specialized for a T* or T const* so giving it a T* const fails since there is no valid specialization.

You can fix this by removing the constness in the declaration of bar with

const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type

or you can change foo to

auto foo = std::cbegin(arr);

if you are okay with it not being const.

like image 170
NathanOliver Avatar answered Sep 21 '22 21:09

NathanOliver


Indeed the const is problematic, you do basically:

std::iterator_traits<const int* const>::value_type // incorrect due to the last const

You might fix it by changing it to

std::iterator_traits<const int*>::value_type // Correct

You might use std::decay or std::remove_cv for that:

const typename std::iterator_traits<std::remove_cv_t<decltype(foo)>>::value_type

(or drop const from foo if relevant).

like image 23
Jarod42 Avatar answered Sep 17 '22 21:09

Jarod42