2012-01-06 21 views
8

Trong tệp tiêu đề của tôi, tôi đã đưa vào sơ đồ std :: và sử dụng không gian tên thích hợp.
Một trong những thành viên của tôi là:Lỗi biên dịch khi sử dụng trình lặp vòng bản đồ

map<unsigned int, double> pT_Spam; 

Và trong tập tin cpp của tôi, tôi cố gắng làm điều gì đó mà tôi đã và đang làm thường xuyên trong một thời gian bây giờ là:

for(map<unsigned int, double>::iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) {/*code*/} 

Ở trên là thậm chí đề cập trong một ví dụ về việc sử dụng std :: map tại cplusplus.com. Mặc dù tôi đã thực hiện khá giống nhau ở các phần khác của mã không gây ra lỗi biên dịch, trên dòng cụ thể này, tôi nhận được lỗi sau từ Cygwin:

error: conversion from `std::_Rb_tree_const_iterator<std::pair<const unsigned int, double> >' to non-scalar type `std::_Rb_tree_iterator<std::pair<const unsigned int, double> >' requested 

Điều này có vẻ hơi lạ. Bất cứ ý tưởng những gì có thể là sai? (Tiêu đề của tôi là, tất nhiên, bao gồm trong cpp của tôi)

+0

Điều đó phàn nàn rằng trình vòng lặp được trả về bởi hàm start() là một hàm const_iterator, nhưng bạn đang gán nó cho một trình lặp. Nhưng tôi không chắc tại sao, điều này cũng đúng với tôi. Trình biên dịch này là gì? – Joe

+0

[begin()] (http://cplusplus.com/reference/stl/map/begin/) dường như cũng có khả năng trả về các biến lặp không phải là const. Tôi sử dụng g ++ của Cygwin trên các cửa sổ. – jathanasiou

Trả lời

16

Dường như tại phạm vi vòng lặp này tồn tại, bản đồ là const. Ví dụ, là vòng lặp trong một phương thức lớp khai báo const, như vậy?

void method() const // const method 
{ 
    // Do stuff. 
} 

hoặc được chuyển làm đối số const, như thế này?

void function(const map<unsigned int, double>& pT_Spam) 
{ 
    // Do stuff. 
} 

Nếu có, bạn phải sử dụng lặp const:

for(map<unsigned int, double>::const_iterator it=pT_Spam.begin() ; it!=pT_Spam.end() ; it++) 
{ 
    /*code*/ 
} 

Hoặc, nếu bạn đang sử dụng C++ 11, sau đó bạn nên sử dụng các từ khóa tự động:

for(auto it=pT_Spam.begin() ; it!=pT_Spam.end(); it++) 
{ 
    /*code*/ 
} 

Vì trong trường hợp bạn đã cho thấy bạn phải sử dụng các trình lặp const, bạn không thể sử dụng chúng để sửa đổi bản đồ hoặc dữ liệu bên trong nó. Đó là const đúng đắn, và đó là một điều tốt :).

+2

-.25 để sử dụng tự động theo cách giết mèo con. ;) –

+1

Cách khác là đánh dấu thành viên là ['mutable'] (http://www.highprogrammer.com/alan/rants/mutable.html). Nhưng đừng nói với bất cứ ai tôi đã nói với bạn rằng :-) –

+0

Phương pháp chạy vòng lặp thực sự là const, và điều đó làm cho tôi hiểu tại sao bản đồ lại là const trong phạm vi của nó. Xem xét tôi không cần phải chỉnh sửa nó trong phương pháp này, const iterators dường như câu trả lời. – jathanasiou

2

Bạn cần phải sử dụng const_iterators cho các bản đồ, vì vậy nó cần được:

for(map<unsigned int, double>::const_iterator it = \\and so on 

Edit: Như đã chỉ ra ở trên là đúng, nhưng đối với hoàn toàn sai lý do (bản đồ có các trình lặp không phải là const. Tôi nghĩ chính xác điều gì? Tôi không biết). Nhiều khả năng bản đồ của bạn được định nghĩa là const (như được chỉ ra trong câu trả lời khác).

+1

Sẽ không gây ra vấn đề khi thay đổi giá trị của chúng (nó ++)? Ngoài ra, tôi đã sử dụng vòng lặp thường xuyên cho các vòng tương tự cho đến nay và không bao giờ có vấn đề. – jathanasiou

+2

Um, cái gì? bản đồ có các trình lặp không phải là const. –

+1

@JohnAthanasiou: Trình biến đổi const-iterator có thể thay đổi không giống như một trình lặp không lặp const. Hãy suy nghĩ 'T const *' so với 'T * const'. –

3

Vâng, lỗi cho biết bạn đang cố gắng truyền một bộ tách const_iterator đến một trình lặp. Bạn nói rằng pT_Spam là một thành viên. Nó là một thành viên của một đối tượng const? Nếu có, bắt đầu() và kết thúc() sẽ trả về const_iterators.

+0

Không chắc chắn phải trung thực, đó là một thành viên tư nhân được khai báo của lớp 'nbclassifier' của tôi, trong khi phương thức thực hiện vòng lặp cũng là một thành viên của lớp đó. – jathanasiou

+0

Cách khác là đánh dấu thành viên là ['mutable'] (http://www.highprogrammer.com/alan/rants/mutable.html). Nhưng đừng nói với bất cứ ai tôi đã nói với bạn rằng :-) –

+0

Const đang đến ở đâu đó. Nếu biến thành viên không được khai báo const, và nếu phương thức không được khai báo const, thì có thể phương thức đang được gọi trên một đối tượng const (mà sẽ làm cho biến thành viên ngầm ẩn). Lỗi trình biên dịch có đi kèm với ngăn xếp cuộc gọi không? EDIT: chờ đợi, nó sẽ phải là một phương pháp const nếu nó đang được gọi là trên một đối tượng const. –

1

cho (bản đồ :: iterator it = pT_Spam.begin();! Nó = pT_Spam.end(); nó ++)

chage nó để

cho (bản đồ :: const_iterator nó = pT_Spam. bắt đầu(); it! = pT_Spam.end(); it ++)

Vì nó trỏ đến giá trị không đổi nên trình vòng lặp cũng phải thuộc loại const.

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