When reading the excerpt from cppreference
If
Iterator
does not have the five member typesdifference_type
,value_type
,pointer
,reference
, anditerator_category
, then this template has no members by any of those names (std::iterator_traits
is SFINAE-friendly)
I automatically thought it meant each member type is defined when they are defined in the iterator itself. But lo and behold, it actually meant if all five are defined, then they are defined.
struct defined
{
using difference_type = int;
using value_type = int;
using pointer = int*;
using reference = int&;
using iterator_category = std::input_iterator_tag;
};
struct undefined
{
using value_type = int;
};
template<typename T>
using value_type = typename std::iterator_traits<T>::value_type;
void foo()
{
using std::experimental::is_detected_v;
static_assert(is_detected_v<value_type, defined>);
static_assert(!is_detected_v<value_type, undefined>);
}
Live
Why is this? I would've thought it is friendlier if they were independent of each other. For example if an algorithm just needs to store the value_type
somewhere and doesn't care about anything else.
template<typename It>
auto amazingfy(It first, It last)
{
typename std::iterator_traits<It>::value_type v;
for(; first != last; first++)
v += *first;
return v;
}
It will fail to compile on some iterator that only defined value_type
, but funnily enough, succeed if it were instead typename It::value_type v;
Some insight can be gathered from corresponding proposal N3844:
With benefit of hindsight, it has from time to time been argued that the SGI STL (and consequently C++98) erred in specifying iterator_traits as a bundle of five type aliases, and that individual iterator-related traits would have been a better design. Even if true, this paper proposes no change to the basic bundled design, keeping to an all-or-nothing principle.
So it looks like it was just to try to approach the current situation very cautiously and make the minimum change required to make the traits SFINAE-friendly. Selective inclusion of the member would lead to the half-defined traits, and apparently, this was considered a potentially far-reaching result.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With