2012-09-13 39 views
6

Nói rằng tôi có 3 chức năng khác nhau mà tôi có thể muốn để trỏ đến:Sử dụng std :: chức năng như một đại biểu trong C++ 11

float test1(int a, int b) { 
    return 7.0f; 
} 

struct TestClass { 
    float test2(int a, int b) { 
     return 5.0f; 
    } 
}; 

struct TestClass2 { 
    float test3(int a, int b) { 
     return 3.0f; 
    } 
}; 

Thông báo như thế nào cả ba sử dụng các đối số tương tự và trở về giá trị. Tôi muốn trừu tượng liệu nó có phải là một hàm thành viên hay không và nó thuộc về lớp nào. Tôi muốn một loại đại biểu có thể được đề cập đến bất kỳ của 3 chức năng này chỉ phụ thuộc vào cách nó được khởi tạo.

Đây là nỗ lực đầu tiên của tôi:

typedef std::function<float(int, int)> MyDelegate; // is this right? 

int main() { 
    TestClass obj; 
    TestClass2 obj2; 

    MyDelegate a = test1; 
    MyDelegate b = std::bind(std::mem_fn(&TestClass::test2), obj); // is this right? 
    MyDelegate c = std::bind(std::mem_fn(&TestClass2::test3), obj2); // is this right? 

    return 0; 
} 

Ý tưởng là tôi muốn cũng để lưu trữ các 'này' con trỏ bên trong wrapper quá. Bằng cách này, nó giống như một ví dụ delegate.For đầy đủ chức năng, gọi 'b (x, y)' nên giống như gọi obj.test2(x, y).

Tôi thậm chí không thể làm cho nó biên dịch, tôi có lẽ không hoàn toàn nắm bắt điều này. Tôi là loại mới cho các thư viện và các lỗi trong VS2012 là thảm họa vô ích. Bất kỳ trợ giúp sẽ được đánh giá cao.

+0

có thể trùng lặp của [callback kiểu C++ 11?] (Http://stackoverflow.com/questions/12338695/c11-styled-callbacks) – Klaim

Trả lời

9

Bạn cần phải biết std::bind phải làm gì với các thông số chức năng khác. Để thực hiện cuộc gọi b(x, y) đại biểu xy với hai thông số chức năng ban đầu bạn cần phải sử dụng placeholders từ std::placeholders namespace:

std::bind(&TestClass::test2, obj, std::placeholders::_1, std::placeholders::_2); 

Và có cũng không cần std::mem_fn (nó hoạt động, mặc dù), vì std::bind đã xử lý chính xác các hàm thành viên (làm cho đối số ngụ ý this tiềm ẩn một đối số đầu tiên rõ ràng, chẳng hạn như std::mem_fn).

3

Bạn cần cung cấp 2 đối số để std :: ràng buộc hoặc cung cấp placeholders để cung cấp cho họ sau:

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, 1, 2); 
c(); //returns result 

HOẶC

std::function<float(int, int)> c = std::bind(&TestClass2::test3, obj2, std::placeholders::_1, std::placeholders::_2); 
c(1, 2); //returns result 

Thông tin thêm về std :: ràng buộc là here.

2

Sử dụng trình biên dịch ++ visual C (CTP 2012) i gián điệp như thế nào họ đã làm std :: chức năng và deliviered giải pháp của riêng tôi để xử lý các chức năng thành viên

sử dụng trông giống như: http://ideone.com/v5zfDn

class Window 
{ 
public: 
    void Show(int number) const 
    { 
     //... 
    } 

    void ShowDynamic(int number) volatile 
    { 
     //... 
    } 
}; 

void ShowWindows(int param) 
{ 
    //... 
} 

int main() 
{ 
    Window window; 

    typedef mezutils::Delegate< void(int) > Notifier; 
    Notifier notifier; 

    notifier = &ShowWindows; 
    notifier(0); 

    notifier = Notifier(&window, &Window::Show); 
    notifier(1); 

    notifier = [](int x) { /*...*/ }; 
    notifier(2); 

    void (*funpc)(int) = func; 
    notifier = funpc; 
    notifier(3); 

    notifier = [](int arg) { printf("asd %d\r\n",arg); }; 
    notifier(4); 
    return 0; 
} 

lớp đại biểu ngoại hình như: http://ideone.com/DebQgR

tất nhiên đây là nguyên mẫu được tạo nên để giải trí, nhưng tôi thích nó vì rõ ràng là

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