2014-10-23 13 views
5

Đối với loại thùng chứa thư viện chuẩn nào là các kiểu chữ trong vùng chứa chứ không phải những gì bạn sẽ ngây thơ nghĩ?C++ khi nào typedefs trong các thùng chứa thư viện chuẩn không phải là những gì bạn mong đợi?

Trong mã, dưới những điều kiện nào vào loại T và container container_type làm kiểm tra tĩnh sau không phải tất cả đánh giá là 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; 

Tôi chỉ biết std::vector<bool>::reference mà không phải là bool& (và có lẽ đây là tương tự cho phiên bản const của chúng).

Còn những người khác không?

+5

Đối với 'map' và' unordered_map', không có 'T'. 'value_type' là' cặp '. –

+0

@Mike Seymour: chắc chắn, nhưng tôi nghĩ rằng bạn có câu hỏi – davidhigh

Trả lời

6

Đối với bất kỳ container chứa đối tượng thuộc loại T, tiêu chuẩn (C++ 11 23.2.1/4) đòi hỏi rằng:

  • container_type::value_typeT
  • container_type::reference là một vế trái của T, tức là một T&
  • container_type::const_reference là một giá trị trái const của T, tức là một const T&

pointerconst_pointer không thuộc bất kỳ yêu cầu nào trong số các yêu cầu Container, chúng chỉ đơn giản là các kiểu chữ tiện lợi trong các vùng chứa tiêu chuẩn, được lấy từ bộ cấp phát của vùng chứa.

Vì vậy, để trả lời câu hỏi của bạn:

value_type, referenceconst_reference phải như bạn mong đợi, nếu không chứa không đáp ứng yêu cầu Container. Lưu ý rằng điều này có nghĩa là (ví dụ: Herb Sutter points out), rằng std::vector<bool>không phải là một vùng chứa theo nghĩa tiêu chuẩn.

pointerconst_pointer là typedefs cho các loại cấp phát, vì vậy khi bạn có một container với cấp phát A, họ sẽ khác với T*T const* bất cứ khi nào std::allocator_traits<A>::pointerstd::allocator_traits<A>::const_pointer khác với họ.

Và để trực tiếp giải quyết các vấn đề mà các container tiêu chuẩn đáp ứng những yêu cầu Container:

  • std::array<T> làm, mỗi 23.3.2.1/3 (với một số ngoại lệ mà không ảnh hưởng đến typedefs trong câu hỏi)
  • std::deque<T> làm, mỗi 23.3.3.1/2
  • std::forward_list<T> làm, mỗi 23.3.4.1/2 (với một số ngoại lệ mà không ảnh hưởng đến typedefs trong câu hỏi)
  • std::list<T> nai s, mỗi 23.3.5.1/2
  • std::vector<T> không (ví T khác hơn bool), mỗi 23.3.6.1/2 (với một số ngoại lệ mà không ảnh hưởng đến typedefs trong câu hỏi)
  • std::set<T> làm, mỗi 23,4. 6.1/2
  • std::multiset<T> làm, mỗi 23.4.7.1/2
  • std::unrdered_set<T> làm, mỗi 23.5.6.1/2
  • std::unordered_multiset<T> làm, mỗi 23.5.7.1/2
  • std::basic_string<T> chứa typedefs trong câu hỏi (để các loại chính xác) theo 21.4./5, mặc dù tiêu chuẩn không yêu cầu rõ ràng để đáp ứng các yêu cầu Container. Lưu ý rằng value_type phụ thuộc vào các đặc điểm của ký tự, vì vậy std::basic_string<T, MyTraits> có thể có value_type khác với T.

std::[unorderd_][multi]map không đủ điều kiện vì chúng lấy nhiều thông số mẫu bắt buộc và sử dụng chúng để tổng hợp value_type.

std::valarray<T> không đủ điều kiện vì chỉ cung cấp loại số value_type và không có loại nào khác.

+0

cảm ơn, câu trả lời hay, nhưng ngay lập tức đặt ra một câu hỏi liên quan: kết hợp 'container_type' và' T' là 'container_type ' không phải là 'Vùng chứa'? Chỉ cho 'std :: vector '? – davidhigh

+0

@davidhigh và khi nào thì hợp pháp đối với người dùng chuyên sử dụng vùng chứa hàng đầu để làm, tốt, bất cứ điều gì? ;) – Yakk

+0

@Yak: xin lỗi, tôi nên nói rằng, tôi đã đề cập đến các loại POD cho 'T'. – davidhigh

Các vấn đề liên quan