For which standard library container types are the typedefs within the container not what you would naively think?
In code, under which conditions on the type T
and the container container_type
do the following static checks not all evaluate to true:
typedef double T;
typedef std::vector<T> container_type;
std::is_same<typename container_type::value_type, T>::value;
std::is_same<typename container_type::reference, T&>::value;
std::is_same<typename container_type::const_reference, T const&>::value;
std::is_same<typename container_type::pointer, T*>::value;
std::is_same<typename container_type::const_pointer, T const*>::value;
I only know of std::vector<bool>::reference
which is not bool&
(and probably this is the same for the const
version thereof).
Are there others?
For any container containing objects of type T
, the standard (C++11 23.2.1/4) requires that:
container_type::value_type
is T
container_type::reference
is an lvalue of T
, i.e. a T&
container_type::const_reference
is a const lvalue of T
, i.e. a const T&
pointer
and const_pointer
are not part of any of the Container
requirements, they are simply convenience typedefs in the standard containers, taken from the container's allocator.
So, to answer your question:
value_type
, reference
and const_reference
must be as you expect, otherwise the container does not satisfy Container
requirements. Notice that this means (as e.g. Herb Sutter points out), that std::vector<bool>
is not a container in the standard sense.
pointer
and const_pointer
are typedefs to the allocator types, so when you have a container with allocator A
, they will differ from T*
and T const*
whenever std::allocator_traits<A>::pointer
and std::allocator_traits<A>::const_pointer
differ from them.
And to directly address the question of which standard containers satisfy these Container
requirements:
std::array<T>
does, per 23.3.2.1/3 (with some exceptions which don't affect the typedefs in question)std::deque<T>
does, per 23.3.3.1/2std::forward_list<T>
does, per 23.3.4.1/2 (with some exceptions which don't affect the typedefs in question)std::list<T>
does, per 23.3.5.1/2std::vector<T>
does (for T
other than bool
), per 23.3.6.1/2 (with some exceptions which don't affect the typedefs in question)std::set<T>
does, per 23.4.6.1/2std::multiset<T>
does, per 23.4.7.1/2std::unrdered_set<T>
does, per 23.5.6.1/2std::unordered_multiset<T>
does, per 23.5.7.1/2std::basic_string<T>
contains the typedefs in question (to the correct types) as per 21.4./5, even though the standard does not explicitly require it to satisfy the Container
requirements. Note that value_type
depends on the character traits, so std::basic_string<T, MyTraits>
can have value_type
other than T
.std::[unorderd_][multi]map
don't qualify because they take more than one mandatory template parameter and use them to synthesise value_type
.
std::valarray<T>
does not qualify because it only provides the value_type
typedef and none of the others.
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