2009-04-27 39 views
44

Tôi muốn lặp qua một std :: map sử dụng BOOST_FOREACH và chỉnh sửa các giá trị. Tôi không thể hiểu được.sử dụng BOOST_FOREACH với std :: map

typedef std::pair<int, int> IdSizePair_t; 
std::map<int,int> mmap;  
mmap[1] = 1; 
mmap[2] = 2; 
mmap[3] = 3; 
BOOST_FOREACH(IdSizePair_t i, mmap) 
    i.second++; 
// mmap should contain {2,3,4} here 

Tất nhiên điều này không thay đổi bất cứ điều gì vì tôi không lặp lại tham chiếu. Vì vậy, tôi thay thế dòng này để thay thế (theo ví dụ trong tài liệu Boost):

BOOST_FOREACH(IdSizePair_t &i, mmap) 

và tôi nhận được lỗi biên dịch:

error C2440: 'initializing' : 
cannot convert from 'std::pair<_Ty1,_Ty2>' to 'IdSizePair_t &' 
    with 
    [ 
     _Ty1=const int, 
     _Ty2=int 
    ] 

Bất kỳ lời đề nghị?

+0

trình biên dịch gì bạn đang sử dụng? Tôi đã thử mã của bạn trên VS2008 và nó hoạt động chính xác. Tôi cũng đã thử nghiệm [answer] (http://stackoverflow.com/questions/795443/using-boostforeach-with-stdmap/795482#795482) của hvint) và nó đã hoạt động. Tôi đang sử dụng tăng 1,36, nếu điều đó quan trọng. –

+0

bạn có thể đã quên &? mà không có nó, nó sao chép các cặp khác, và constness sẽ không quan trọng sau đó. –

Trả lời

66

Sự cố xảy ra với thành viên đầu tiên của cặp, cần là const. Hãy thử điều này:

typedef std::map<int, int> map_t; 
map_t mmap; 
BOOST_FOREACH(map_t::value_type &i, mmap) 
    i.second++; 
+0

+1. bạn đánh tôi sau vài giây: D –

+0

Cảm ơn, hvint. Điều đó đã làm điều đó. Ngoài ra (sau khi đọc bình luận của bạn) tôi nhận ra rằng một cách khác để sửa chữa nó là thay đổi dòng đầu tiên của mã ban đầu của tôi thành: typedef std :: pair IdSizePair_ty; (cho phép tôi lặp lại bằng cách tham khảo) – kmote

+0

kmote, vâng, thực sự đó là những gì tôi đề xuất trong câu trả lời của tôi (mà tôi đã xóa khi tôi nhìn thấy của một người). Ngoài ra, bạn có biết tại sao nó cư xử theo cách đó không? Tôi sẽ lấy lại của tôi nếu bạn cần một số lời giải thích. –

4

Một lựa chọn khác là sử dụng BOOST_FOREACH_PAIR, xem câu trả lời của tôi ở đây:

BOOST_FOREACH & templates without typedef

+1

Tôi thích giao diện của BOOST_FOREACH_PAIR, nhưng tôi không thấy bất kỳ tham chiếu chính thức nào về nó và nó không có trong phiên bản 1.46 tôi đang sử dụng.Đã bao giờ nó được đưa vào bản phát hành chính thức chưa? –

+0

Đó chỉ là một macro tự chế - nó chưa bao giờ được triển khai. Kết thúc như là một wontfix (ủng hộ của C + + 11 phạm vi dựa trên vòng) trong https://svn.boost.org/trac/boost/ticket/3469 – baderous

21

Đây là một chủ đề cũ, nhưng có một giải pháp thuận tiện hơn.

tăng cường có khái niệm về 'bộ điều hợp dải ô' thực hiện phép biến đổi trên phạm vi trình lặp. Có các bộ điều hợp dải ô cụ thể cho trường hợp sử dụng chính xác này (lặp qua các khóa hoặc giá trị bản đồ): boost::adaptors::map_valuesboost::adaptors::map_keys.

Vì vậy, bạn có thể duyệt qua các giá trị bản đồ như thế này:

BOOST_FOREACH(int& size, mmap | boost::adaptors::map_values) 
{ 
    ++size; 
} 

Thông tin thêm here.

+0

Đối với giải pháp này ' 'cần được bao gồm. – scai

0

Tính đến C++ 11 xem xét việc sử dụng từ khóa tự động:

std::map<int,int> mmap;  
mmap[1] = 1; 
mmap[2] = 2; 
mmap[3] = 3; 

BOOST_FOREACH(auto& mpair, mmap) 
    mpair.second++; 

//mmap will contain {2,3,4} here 
Các vấn đề liên quan