2011-11-14 68 views
7

iterating trên một vector hoạt động:std :: for_each qua std :: set, C++ 11

std::vector<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

nhưng chưa kết thúc một tập (biên dịch lỗi):

std::set<int> collection = {2, 3, 4, 5435345, 2}; 
std::for_each(collection.begin(), collection.end(), [](int& i){cout << i << endl;}); 

Tại sao có thể' t Tôi lặp qua một số std::set với std::for_each?

Câu hỏi thưởng: Ngoài ra, tôi muốn thay đổi số int& trong đối số lambda thành auto&, tại sao điều này không thể tự động được suy luận?

Trả lời

19

std::set<T>::value_typeT const, không T; do đó, đối số cho lambda của bạn phải là loại giá trị (tức là, sao chép) hoặc int const& (và về mặt kỹ thuật hoặc int const volatile&), không phải là int&. Ví dụ: công trình này:

std::set<int> collection{2, 3, 4, 5435345, 2}; 
std::for_each(
    collection.begin(), 
    collection.end(), 
    [](int const& i) { std::cout << i << std::endl; } 
); 

Bonus câu hỏi: Ngoài ra, tôi muốn thay đổi int& trong lập luận của lambda để auto&, tại sao có thể không này được tự động suy luận?

Vì tiêu chuẩn cho biết không thể; về mặt lịch sử, tôi tin rằng điều này là do các tương tác quá phức tạp giữa các lambdas và các khái niệm (trước khi các khái niệm được loại bỏ khỏi bản nháp). Tuy nhiên, tôi nghe tin đồn rằng lỗi đầu tiên báo cáo cho tiêu chuẩn mới (C++ 11) sẽ giải quyết chính xác điều này, vì vậy có thể bạn sẽ thấy hỗ trợ cho điều này được thêm vào trình biên dịch lựa chọn của bạn trong vòng một hoặc hai năm tới. EDIT: Ồ, hãy xem, C++ 14 hiện có lambdas đa hình ...

+0

bạn đã nghe thấy điều đó ở đâu? Trên blog của Herb sutter, ông đề cập rằng họ sẽ không thêm lambda đa hình cho đến khi vấn đề khái niệm đã được giải quyết, bởi vì họ vẫn muốn có một tính năng giống như khái niệm trong tương lai. –

+0

lol những gì một chính trị gia. :) Vì vậy, đưa ra khỏi câu trả lời, bạn sẽ? – wilhelmtell

0

Bạn sẽ có thể lặp qua một bộ. Tuy nhiên, lưu ý rằng vì phần tử trong tập hợp cũng là khóa của nó, nó không thể sửa đổi được. Thay đổi mã của bạn để tham chiếu const và sử dụng cbegin/cend thay vào đó, bất kể là có được đặt hay không khi bạn không sửa đổi các phần tử.

1

Trình lặp lại set<int> lặp lại là const int&. Vì vậy, bạn không thể chuyển nó thành thông số int& mà không cần const. Hãy thử hoặc là đồng bằng (int i) hoặc (const int& i).

Và đó thực sự không phải là một trong những nơi bạn được phép sử dụng auto. Tôi nghĩ rằng auto chỉ hoạt động trong khai báo với trình khởi tạo hoặc làm trình giữ chỗ cho loại trả về theo sau.

3

Về câu hỏi tiền thưởng: Đối số chức năng "tự động" không cụ thể đối với lambdas. Bạn cũng có thể hỏi tại sao chúng tôi không cho phép tất cả các chức năng được khai báo là f(auto x, auto y). Nhưng điều đó chỉ có nghĩa là bạn về cơ bản muốn thay thế tất cả các chức năng bằng các mẫu chức năng. Điều đó được coi là không hoạt động tốt với ngôn ngữ C++ hiện có và hệ thống kiểu đặc biệt. Nếu bạn muốn một mẫu hàm, đã có một cú pháp và cơ chế hiện có, và tuyên bố các đối số "tự động" không phải là cách để đi.

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