2011-07-08 23 views
5

Làm cách nào để tạo hàm lambda bằng cách sử dụng boost hoặc stl để khớp với thông số boost::function được mong đợi bởi F trong đoạn mã thứ ba trong main?Làm cách nào để tạo một hàm lambda để khớp với tham số hàm boost :: mà không sử dụng C++ 0x?

#include <iostream> 
#include <boost/function.hpp> 

void F(int a, boost::function<bool(int)> f) { 
    std::cout << "a = " << a << " f(a) = " << f(a) << std::endl; 
} 

bool G(int x) { 
    return x == 0; 
} 

int main(int arg, char** argv) { 
    // C++0x 
    F(123, [](int i) { return i==0; }); 

    // Using seperate function 
    F(0, &G); 

    // How can I do it in place without C++0x 
    F(123, /* create a lambda here to match */); 
} 

Tôi không thể sử dụng C++ 0x và muốn tránh tạo một số chức năng riêng biệt. Tôi có thể sử dụng một cái gì đó khác mà boost::function nếu điều đó giúp, ưu tiên của tôi là tạo ra lambda ngắn gọn.

+1

Tôi bây giờ tự hỏi ... làm thế nào mà bạn không thể sử dụng C++ 0x nhưng bạn muốn sử dụng 'std :: function' là một phần của C++ 0x? BTW, hãy xem thư viện lambda tăng cường, vì nó có thể là những gì bạn đang tìm kiếm. –

+2

@David: boost :: function not std :: function –

Trả lời

7
#include <functional> // STL 
#include <boost/lambda/lambda.hpp> // Boost.Lambda 
#include <boost/spirit/include/phoenix_core.hpp>  // Boost.Pheonix 
#include <boost/spirit/include/phoenix_operator.hpp> // Boost.Pheonix also 

... 

// Use STL bind without lambdas 
F(0, std::bind2nd(std::equal_to<int>(), 0)); 
F(123, std::bind2nd(std::equal_to<int>(), 0)); 

// Use Boost.Lambda (boost::lambda::_1 is the variable) 
F(0, boost::lambda::_1 == 0); 
F(123, boost::lambda::_1 == 0); 

// Use Boost.Phoenix 
F(0, boost::phoenix::arg_names::arg1 == 0); 
F(123, boost::phoenix::arg_names::arg1 == 0); 

Bạn có thể muốn thêm một số using namespace để đơn giản hóa mã.

Boost.Lambda là để xác định functors nội tuyến bằng cú pháp giống C++, trong khi Boost.Phoenix là ngôn ngữ lập trình hàm được xây dựng trên C++ lạm dụng (☺) cú pháp và khả năng tính toán thời gian biên dịch. Boost.Phoenix mạnh hơn nhiều so với Boost.Lambda, nhưng trước đây cũng mất nhiều thời gian hơn để biên dịch.

+0

Ngoài ra, với Boost 1.47, Boost.Lambda chính thức không được hỗ trợ bởi Boost.Phoenix v3. Tức là, Boost.Lambda hiện là thư viện cũ, không có ý định sử dụng trong mã mới. – ildjarn

-1

Câu trả lời ngắn gọn: không.

C++ 0x lambdas được phát minh để thực hiện chính xác những gì bạn muốn. Chúng thực sự không có gì khác ngoài cách tạo Increment trong ví dụ bên dưới ẩn danh/nội dòng. Đây là cách chỉ để có được một chức năng ẩn danh trong bất kỳ C++ chuẩn nào.

struct Increment { 
    int & arg; 
    Increment (int a) : arg (a) {} 
    void operator() (int & i) 
     {arg += i;} 
}; 

void foo (const std :: vector <int> & buffer, int x) 
{ 
    std :: for_each (
     buffer .begin(), buffer .end(), 
     Increment (x)); // C++98 

    std :: for_each (
     buffer .begin(), buffer .end(), 
     [&x] (int & i) {x += i;}); // C++0x 
} 

Điều kỳ diệu chỉ khoảng lambdas là loại của họ không thể được đánh vần nhưng trình biên dịch có thể ràng buộc kiểu ẩn nội bộ để std::function (hoặc thậm chí là một con trỏ hàm C dưới một số trường hợp).

Tôi đăng mã ở trên vì tôi nghĩ câu hỏi của bạn có thể không có nghĩa là bạn nghĩ câu hỏi đó. Lambdas chắc chắn là một điều C++ 0x nhưng trong ví dụ này, Increment là một đóng cửa . (Một số sẽ nói nó chỉ trở thành một đóng cửa nếu bạn trả lại nó và biến bị ràng buộc thoát khỏi bối cảnh mà nó bị ràng buộc - đó là nitpicking nhưng đó là những gì, nói, Javascript hiện).

Câu hỏi của bạn về lambdas hoặc bao đóng?

+0

Tại sao điều này lại được bình chọn? Mã là rắn. EDIT: Ngoại trừ constructor 'Increment' nên dùng' int & 'chứ không phải' int'. –

+0

@Mike: Có lẽ vì có nhiều thư viện lambda cho C++ 03. (Tôi đã không downvote.) – ildjarn

+0

Tôi nghĩ rằng chúng tôi chỉ không đồng ý về những gì "lambda" có nghĩa là. Các thư viện lambda C++ 03 "có thể * trông * giống như lambdas, do tác phẩm thông minh và khó khăn của các tác giả, nhưng chúng là * không * lambdas. Tôi không thể không cảm thấy hơi khó thực hiện bởi :-( – spraff

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