2016-07-24 23 views
10

Xét đoạn mã sau:Giá trị của các kiểu nguyên thủy trong std :: map đã được khởi tạo chưa?

map<int,int> m; 
for(int i=0;i<10000;++i) m[i]++; 
for(int i=0;i<10000;++i) printf("%d",m[i]); 

Tôi nghĩ rằng các giá trị in ra sẽ được undefined vì loại nguyên thủy không có constructor mặc định, nhưng ở đây tôi có 10000 1s mỗi khi tôi kiểm tra.

Tại sao nó được khởi tạo?

+4

0 là giá trị pháp lý đối với các biến không xác định. –

Trả lời

12

Khi gọi operator[] và khóa bị thiếu, giá trị được khởi tạo bằng cách sử dụng biểu thức mapped_type() là hàm tạo mặc định cho loại lớp và khởi tạo zero cho các loại tích phân.

+2

Hmm thực sự, bạn có chắc đây là câu trả lời không? Trên [map :: operator []] (http://www.cplusplus.com/reference/map/map/operator [] /) nó nói: " Cuộc gọi đến chức năng này tương đương với: (* ((this-> insert (make_pair (k, mapped_type()))).) đầu tiên "cho biết giá trị khởi tạo của cặp không quan trọng –

+1

Bạn có chắc chắn với cplusplus.com? – LogicStuff

+1

Chris có một điểm. Hàm khởi tạo mặc định của 'cặp' rõ ràng là không được sử dụng - thành viên' first' của cặp là chỉ số nguyên 'i' chạy từ 0 đến 10000 ở đây.Nếu ctor mặc định sẽ được sử dụng, thành viên 'first' sẽ bằng 0, và vì bản đồ không thể chứa các khóa trùng lặp nên chỉ có một mục nhập bản đồ duy nhất. Như chúng ta biết rằng 10000 cái đã được in, chúng ta biết rằng ctor cặp mặc định đã không được sử dụng. – MSalters

3

Xem https://www.sgi.com/tech/stl/stl_map.h

_Tp& operator[](const key_type& __k) { 
    iterator __i = lower_bound(__k); 
    // __i->first is greater than or equivalent to __k. 
    if (__i == end() || key_comp()(__k, (*__i).first)) 
     __i = insert(__i, value_type(__k, _Tp())); 
    return (*__i).second; 
    } 

Trong ví dụ của bạn, _Tp là int, và int() là 0

#include <iostream> 
using namespace std; 
int main() { 
    int x = int(); 
    cout << x << endl; 
    return 0; 
} 

Ngoài ra:

nhờ @MSalters người nói về mã trên là SGI thay vì std :: map, Nhưng tôi nghĩ nó giống như ...

+0

Đó thực sự là lớp STL 'map', không phải' std :: map'. Cái thứ hai được lấy cảm hứng từ cái cũ, nhưng có những khác biệt nhỏ. Và câu hỏi này là về một chi tiết nhỏ. Nhưng có, vì nó xảy ra không có sự khác biệt ngay tại đây. – MSalters

+0

bạn nói đúng, có nhiều phiên bản stl, SGI, STLPort, phiên bản microsoft, v.v. – kaitian521

+0

Nếu Microsoft từng có thư viện có nguồn gốc từ STL, thì cách đây 2 thập kỷ. (VC4 có lẽ, không nhớ lại chi tiết). Họ chắc chắn chuyển sang thực hiện Dinkumware của VC6, một C++ 98 Thư viện chuẩn thực hiện. – MSalters

5

std::map::operator[] chèn giá trị mới nếu nó không tồn tại. Nếu chèn được thực hiện, giá trị được ánh xạ được khởi tạo bởi hàm tạo mặc định cho các kiểu lớp hoặc zero-initialized nếu không.

0

Trong tiêu chuẩn C++ 14, phần [map.access] văn bản là:

T& operator[](const key_type& x);

  1. Effects: Nếu không có tương đương chìa khóa để x trong bản đồ, chèn value_type(x, T()) vào bản đồ .

Vì vậy, cũng như quy định bởi câu trả lời Joseph Garvin của, kết quả của biểu thức mapped_type() là những gì được chèn vào. Kiểu khởi tạo này được gọi là value-initialization.

Ý nghĩa của việc khởi tạo giá trị không đơn giản như được cung cấp trong các câu trả lời khác, đối với các loại lớp. Nó phụ thuộc vào loại nhà xây dựng mà loại lớp có, và liệu lớp đó có phải là tổng hợp hay không, như được giải thích bởi liên kết cppreference.

Đối với int như trong câu hỏi này, giá trị khởi tạo có nghĩa là int được đặt thành 0.

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