C ++, when typedefs in standard library containers are not what you expect?

For what standard types of library containers are typedefs in a container, what do you naively think?

In code in which conditions like T and container container_type perform the following static checks, not everyone evaluates 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 std::vector<bool>::reference , which is not bool& (and probably this is the same for the const version).

Are there any others?

+5
source share
1 answer

For any container containing objects of type T , the standard (C ++ 11 23.2.1 / 4) requires that:

  • container_type::value_type T
  • container_type::reference is the value of l T , i.e. a T&
  • container_type::const_reference is const lvalue T , i.e. a const T&

pointer and const_pointer are not part of any of the requirements of Container , they are just convenient typedefs in standard containers taken from the container dispenser.

So, to answer your question:

value_type , reference and const_reference should be what you expect, otherwise the container does not satisfy the requirements of the Container . Note that this means (for example, indicating Herb Sutter ) that std::vector<bool> not a container in the standard sense.

pointer and const_pointer are typedefs for dispenser types, so when you have a container with dispenser A , they will be different from T* and T const* when std::allocator_traits<A>::pointer and std::allocator_traits<A>::const_pointer are different from them.

And to directly address the issue of which standard containers satisfy these Container requirements:

  • std::array<T> does, on 23.3.2.1/3 (with some exceptions that do not affect typed responses)
  • std::deque<T> does, on 23.3.3.1/2
  • std::forward_list<T> does, in accordance with 23.3.4.1/2 (with some exceptions that do not affect typed responses)
  • std::list<T> does, for 23.3.5.1/2
  • std::vector<T> does (for T except bool ), on 23.3.6.1/2 (with some exceptions that do not affect typed responses)
  • std::set<T> does, on 23.4.6.1/2
  • std::multiset<T> does, for 23.4.7.1/2
  • std::unrdered_set<T> does, on 23.5.6.1/2
  • std::unordered_multiset<T> does, on 23.5.7.1/2
  • std::basic_string<T> contains the specified typedefs (to the correct types) according to 21.4./5, even if the standard does not explicitly require that it satisfy the requirements of the Container . Note that value_type depends on character traits, so std::basic_string<T, MyTraits> can have value_type other than T

std::[unorderd_][multi]map do not qualify because they accept more than one required template parameter and use them to synthesize value_type .

std::valarray<T> not suitable since it provides only a value_type typedef and none of the others.

+6
source

Source: https://habr.com/ru/post/1205369/


All Articles