2012-01-05 36 views
19

Tôi đang cố gắng để thực hiện một bản đồ với một hàm lambda trong C++ 11 như vậySử dụng Lambdas trong Maps

std::map<int, int, [](const int&a, const int& b) { return a < b; }> test; 

nhưng điều đó không thành công với

error: type/value mismatch at argument 3 in template parameter list for ‘template<class _Key, class _Tp, class _Compare, class _Alloc> class std::map’

error: expected a type, got ‘{}’

error: invalid type in declaration before ‘;’ token

Bất cứ lời khuyên?

+1

Bạn đã cung cấp một lambda, tức là một đối tượng; tham số mẫu phải là _type_, không phải là một thể hiện của một loại. – ildjarn

+0

Tham khảo [C++ priority_queue với lỗi so sánh lambda] (http://stackoverflow.com/questions/5807735/c-priority-queue-with-lambda-comparator-error) và [Có thể 'loại' của một biểu thức lambda được thể hiện?] (http://stackoverflow.com/questions/3867276/can-the-type-of-a-lambda-expression-be-expressed). –

Trả lời

25

Bạn cần chuyển loại lambda làm đối số mẫu, chứ không phải chính lambda.

auto mycomp = [](const int&a, const int& b) { return a < b; }; 
std::map<int, int, decltype(mycomp)> test(mycomp); 

Mặc dù trên thực tế, kể từ khi lambda của bạn không có ảnh chụp, nó có thể thực sự được lưu trữ trong một con trỏ hàm, vì vậy cách khác, bạn có thể làm điều này::

std::map<int, int, bool(*)(const int&,const int&)> 
    test([](const int&a, const int& b) { return a < b; }); 

Mặc dù những gì bạn muốn điều này là Tôi tìm thấy đầu tiên dễ đọc hơn nhiều. Mặc dù sử dụng kiểu con trỏ hàm là linh hoạt hơn. tức là nó có thể chấp nhận bất kỳ con trỏ hàm hoặc lambda không bắt nào khớp với chữ ký đó. Nhưng nếu bạn thay đổi lambda của bạn để được chụp, nó sẽ không hoạt động. Đối với một phiên bản linh hoạt hơn, bạn có thể sử dụng std::function, tức là:

std::map<int, int, std::function<bool(const int&, const int&)>> 

Điều đó sẽ làm việc với bất kỳ chức năng, lambda (chụp hay không) hoặc chức năng đối tượng, miễn là các chữ ký phù hợp.

+0

Khá đúng, ông Lindley. –

+0

Lưu ý rằng nếu 2 bản đồ được khai báo, chúng sẽ có 2 loại khác nhau và không tương thích. –

+0

@Jesse: Đó sẽ là một đối số cho việc sử dụng kiểu con trỏ hàm thay vì decltype trên lambda, giống như tôi đã làm trong ví dụ thứ hai của mình. Nhưng tốt hơn (đối với tính tương thích, không hiệu quả) sẽ sử dụng một 'std :: function', sau đó nó sẽ tương thích ngay cả với lambdas chụp và các đối tượng chức năng khác. –

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