2009-09-04 35 views
24

Tôi muốn có một bản đồ vectơ, (nhưng tôi không muốn sử dụng con trỏ cho vector nội bộ), có thể không?bản đồ vectơ trong STL?

// define my map of vector 
map<int, vector<MyClass> > map; 

// insert an empty vector for key 10. # Compile Error 
map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>)); 

Tôi biết rằng nếu tôi đã sử dụng con trỏ cho vector, như sau, nó sẽ là tốt, nhưng tôi tự hỏi, nếu tôi có thể tránh sử dụng con trỏ và sử dụng cấu trúc dữ liệu trên (Tôi không muốn tự xóa)

// define my map of vector 
map<int, vector<MyClass>* > map; 

// insert an empty vector for key 10. 
map.insert(pair<int, vector<MyClass>* >(10, new vector<MyClass>)); 

Trả lời

29

Cấu trúc dữ liệu đầu tiên sẽ hoạt động. Bạn có thể muốn typedef một số mã để làm cho công việc trong tương lai dễ dàng hơn:

typedef std::vector<MyClass>  MyClassSet; 
typedef std::map<int, MyClassSet> MyClassSetMap; 

MyClassSetMap map; 
map.insert(MyClassSetMap::value_type(10, MyClassSet())); 

hoặc (nhờ quamrana):

map[10] = MyClassSet(); 
15

Có, nhưng dòng thứ hai của bạn nên là:

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>())); 

Điều này chèn một cặp bao gồm số nguyên 10 và một vectơ trống. Cả hai sẽ được sao chép, và nếu bạn đang xử lý các vectơ lớn thì bạn sẽ cần phải cẩn thận về các bản sao.

Ngoài ra: không gọi biến "bản đồ" trong khi using namespace std. Bạn đang sợ tôi ;-)

+4

Thậm chí còn dễ dàng hơn khi viết 'map.insert (std :: make_pair (10, vector ())); ' – xtofl

+3

cảm ơn! trang web này thực sự tuyệt vời! – chen

+0

@xtofl: có, tôi có nghĩa là "nên" theo nghĩa "để thoát khỏi lỗi trình biên dịch". fbrereton cũng làm cho các điểm tốt về việc làm cho mã ngắn gọn hơn. –

2

Bạn chỉ mất một cặp ngoặc đơn:

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>())); 

Ngẫu nhiên, có một hàm helper std :: make_pair mà sẽ chăm sóc của suy ra như đối số mẫu:

map.insert(make_pair(10, vector<MyClass>())); 

Cân nhắc việc sử dụng con trỏ tới vector được phân bổ động thay vì là một ý tưởng khá tồi, vì điều này sẽ khiến bạn chịu trách nhiệm quản lý cá thể. Ngoài ra, vì bản đồ không bao giờ di chuyển nội dung của nó xung quanh trong bộ nhớ, không có gì để đạt được hiệu suất khôn ngoan không.

6

Sử dụng typedefs từ fbrereton bạn cũng có thể làm điều này:

typedef std::vector<MyClass>  MyClassSet; 
typedef std::map<int, MyClassSet> MyClassSetMap; 

MyClassSetMap map; 
map[10]=MyClassSet(); 

Bạn có thể sử dụng operator[] thay vì insert(). này giúp tiết kiệm trên tiếng ồn dòng một chút.

+1

Tôi nghĩ rằng bạn có nghĩa là bản đồ [10] = MyClassSet(); Trên thực tế nó cũng nên có thể viết bản đồ chỉ [10]; (để thêm một yếu tố bất ngờ nhỏ). – UncleBens

+0

@UncleBens - Rất tiếc, tôi sẽ sửa chữa! – quamrana

+0

Điều này phụ thuộc vào cách thức này được gọi. Chèn có thể nhanh hơn nếu bạn biết sẽ không có xung đột. –

4

Bạn nên đọc thông báo lỗi biên dịch. Họ thường cung cấp cho bạn tất cả các thông tin mà bạn cần.
Mã của bạn cung cấp lỗi 'illegal use of this type as an expression' trong chuỗi đó. Điều đó có nghĩa là bạn sử dụng loại, không phải là một đối tượng. Để sử dụng một đối tượng, bạn có thể chỉ cần thêm() để gọi hàm tạo không có đối số.

map.insert(pair<int, vector<MyClass> >(10, vector<MyClass>())); 

Bằng cách này bạn có thể sử dụng lệnh std :: make_pair để tạo cặp. Nó suy ra các loại đối số, vì vậy không cần phải chỉ rõ chúng.

map.insert(make_pair(10, vector<MyClass>())); 
+0

+1 để gợi ý đọc lỗi trình biên dịch. Tuy nhiên, chúng là trình biên dịch cụ thể. Với GCC, lỗi là "biểu thức chính dự kiến ​​trước ...", IMO có ý nghĩa chung của "có gì đó sai ở đây" - bạn chỉ cần xem xét kỹ mã để tìm ra. (Cố gắng biên dịch với các trình biên dịch khác nhau có thể là một ý tưởng hay, tôi đã có thông báo lỗi không chỉ không rõ ràng mà còn gây hiểu lầm, ví dụ "tham số thứ hai sai" trong đó lỗi trong tham số đầu tiên.) – UncleBens

3

Bạn có thể sử dụng toán tử [].
Chúng sẽ chèn giá trị vào bản đồ.

map[10]; // create the 10 element if it does not exist 
     // using the default constructor. 

Nếu bạn đang sử dụng ngay sau khi xây dựng thì:

std::vector<MyClass>& v = map[10]; 

Bây giờ xây dựng của nó và bạn có một tài liệu tham khảo địa phương để các đối tượng.

5

Sử dụng chức năng hoán đổi để thêm hiệu quả vectơ của bạn.

map<int, vector<SomeClass> > Map; 

vector<SomeClass> vec; 
//...add elements to vec 

Map[1] = vector<int>(); 
// swap the empty vector just inserted with your vector. 
Map[1].swap(vec); 
2

Cho phép sử dụng một chút C++ 11;)

typedef std::vector<MyClass>  MyClassSet; 
typedef std::map<int, MyClassSet> MyClassSetMap; 

MyClassSetMap map; 
map.emplace(myid, MyClassSet()); 

Để biết nếu điều này được chèn bạn có thể làm:

const auto result = map.emplace(myid, MyClassSet()); 
return (result.second) 
? "Is_OK" 
: "Maybe "+myid+" exists\n"; 

Và đây là flagship của C++ 11 và bản đồ .... làm thế nào để chèn vào bản đồ này một cặp nếu nó không tồn tại và nếu nó tồn tại chỉ cần chèn một phần tử mới trong vectơ ....

const auto result = map.emplace(myid, MyClassSet()); 
result.first->second.emplace(objSet); 

Tôi hy vọng cung cấp thông tin hữu ích !!!

+1

Nếu bộ nhớ của tôi phục vụ, lớp bản đồ không cung cấp chức năng "emplace_back" (nó tương đối thuộc về vectơ và các vùng chứa khác). bản đồ trong tay khác cung cấp các hàm "emplace" và "emplace_hint" – atari83

+0

Có, hoàn toàn đồng ý. Ediited, Cảm ơn! – GutiMac

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