2012-03-02 28 views
7

Hãy tưởng tượng tôi có chức năng miễn phí sau đây và functor:Hàm/functors làm tham số mẫu. Chúng có thể được lưu trữ không?

void myFreeFunction(void) 
{ 
    cout << "Executing free function" << endl; 
} 

struct MyFunctor 
{ 
    void operator()(void) 
    { 
     cout << "Executing functor" << endl; 
    } 
}; 

Như discribed bởi this answer, tôi có thể vượt qua chức năng hoặc functor tôi như là một mẫu đối số chức năng khác:

template <typename F> 
void doOperation(F f) 
{ 
    f(); 
} 

Và sau đó gọi:

doOperation(myFreeFunction); 
doOperation(MyFunctor()); 

Cho đến nay rất tốt. Nhưng nếu tôi muốn một cái gì đó như sau:

template<typename Callback> 
class MyClass 
{ 
private: 
    Callback mCallback; 

public: 
    MyClass(){} 

    void execute() 
    { 
     mCallback(); 
    } 
}; 

Trong trường hợp này tôi chỉ định chức năng/functor khi tôi khai báo lớp nhưng không gọi cho đến sau này. Nó hoạt động cho functors:

MyClass<MyFunctor> myClass1; 
myClass1.execute(); 

Nhưng không phải cho các chức năng:

MyClass<myFreeFunction> myClass2; 
myClass2.execute(); 

Compiler nói:

lỗi C2923: 'MyClass': 'myFreeFunction' không phải là một mẫu đối số kiểu hợp lệ cho thông số 'Gọi lại'

Điều này là hợp lý ... nhưng bạn sẽ thế nào cấu trúc này?

Lưu ý: Tôi biết về std :: function và có thể kết thúc bằng cách sử dụng tính năng này. Nó có thể đo được chậm hơn mặc dù vậy tôi đang xem xét tất cả các tùy chọn.

Cảm ơn,

David

+0

sử dụng boost :: bind() và boost :: function(), bạn có thể thực hiện những gì bạn đang tìm kiếm. Nếu quan tâm, tôi có thể cung cấp một ví dụ. – Lou

+0

Cảm ơn, nhưng như đã lưu ý ở phần cuối, tôi đã biết về std :: function như một giải pháp. Nó dường như có hiệu suất trên không mặc dù là kết quả của hàm không được inlined. – PolyVox

Trả lời

7

Vấn đề là freefunction đó không phải là một loại nhưng một yếu tố của một số (int trường hợp này một con trỏ hàm.

để khắc phục vấn đề này, bạn cần phải vượt qua các chức năng trong, trong xây dựng, tuy nhiên bạn vẫn cần phải biết chính xác loại

myclass<call_back_t> my_class(call_back); 

EDIT:. trong C++ 11 loại có thể nhận được từ decltype(call_back)

tuy nhiên nhận được cuộc gọi trở lại có thể trở nên khó chịu nó thường là dễ dàng hơn nhiều để tạo ra một chức năng máy phát điện

//this should be in the namespace of the class or a static member of it 
template<FuncType> 
myclass<FuncType> make_class(FuncType func) 
{ 
    return myclass<FuncType>(func); 
} 
//called like 
myclass mc=make_class(&my_callback); 

Đừng để có được để thay đổi các nhà xây dựng

template<typename CallBack> 
myclass{ 
private: 
    CallBack call_back; 
public: 
    myclass(CallBack call_back_) 
    : call_back(call_back_) 
    {} 
}; 

hoặc một cái gì đó như thế

+0

Tuyệt vời, cảm ơn thông tin.Tôi đã điều chỉnh MyClass như bạn đề nghị và bây giờ tôi có thể làm: – PolyVox

+0

Meh, có vẻ như tôi không thể thêm các câu hỏi khác trong nhận xét. Về cơ bản giải pháp của bạn không hoạt động cho cả functors và chức năng vì vậy cảm ơn cho điều đó. Có một vấn đề cú pháp nhỏ mà tôi có với các giáo viên, nhưng tôi sẽ hỏi một câu hỏi mới nếu tôi không thể giải quyết được. – PolyVox

+0

@PolyVox Chỉ cần chỉnh sửa bài đăng của bạn hoặc đăng nó ở đây đang cố gắng và giúp đỡ – 111111

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