2012-04-05 61 views
9

Tôi đang cố hiểu khái niệm và lỗi. Chuyện gì thế này?std :: chức năng với các chức năng thành viên không tĩnh

class A 
{ 
public: 
    A() 
    { 
     std::function<void(int)> testFunc(&A::func); 
    } 

private: 
    void func(int) {} 
} 

câu hỏi của tôi, là nó có thể tạo ra bất kỳ loại của đối tượng đó có thể gọi là một thành viên của một trường hợp cụ thể mà std :: chức năng hoạt động như một con trỏ hàm thành viên, trừ trường hợp mà không cần định nghĩa kiểu lập dị mà có thể không được sử dụng như các tham số hàm trong các lớp kế thừa. ví dụ:

class A 
{ 
public: 
    A() 
    { 
     index[WM_CREATE] = &A::close; 
     index[WM_DESTROY] = &A::destroy; 
    } 

protected: 
    map<UINT msg, void (A::*)(HWND, UINT , WPARAM, LPARAM)> index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public: 
    B() 
    { 
     index[WM_CREATE] = &B::create; // error because it's not a pointer of type A::* 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

Tôi đang nghĩ đến tôi đi đúng hướng của việc sử dụng std :: chức năng như vậy:

class A 
{ 
public:    //   Gigantic stl error with these two 
    A()    //       | 
    {    //       V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::close); 
     index[WM_DESTROY] = std::function<void(HWND, UINT, WPARAM, LPARAM>(&A::destroy); 
    } 

protected: 
    map<UINT msg, std::function<void(HWND, UINT, WPARAM, LPARAM)> > index; 
    void close(HWND,UINT, WPARAM, LPARAM); 
    void destroy(HWND, UINT, WPARAM, LPARAM); 
}; 

class B : public A 
{ 
public:     //    and this one 
    B()     //      | 
    {      //      V 
     index[WM_CREATE] = std::function<void(HWND, UINT, WPARAM, LPARAM)>(&B::create); 
    } 
private: 
    void create(HWND, UINT, WPARAM, LPARAM); 

}; 

nếu ai đó có thể giải thích những gì các lỗi khó hiểu khổng lồ nghĩa và cách sửa chúng, tôi sẽ đánh giá cao nó.

+0

Khi bạn nói "gọi thành viên của một trường hợp cụ thể trong đó' std :: function' hoạt động giống như con trỏ hàm thành viên ", điều đó có nghĩa là cá thể cụ thể được chỉ định tại thời điểm tạo hàm' std :: 'đối tượng? Đây là những gì chữ 'void (int)' gợi ý, nhưng sau đó đối tượng kết quả sẽ không hành động "giống như một con trỏ hàm thành viên", nó sẽ hoạt động như một callback/functor. Nếu mặt khác, bạn có nghĩa là đối tượng 'std :: function' kết quả thực sự hoạt động giống như một con trỏ hàm thành viên, thì chữ ký là sai (ví dụ: nó có thể là' void (A &, int) 'thay thế). Đó là nó? –

+0

không chắc chắn những gì một callback/functor là, nhưng nó kinda âm thanh như chúng tôi đang phân biệt giữa một chức năng tĩnh và một chức năng không tĩnh, và tôi muốn nó là một chức năng không tĩnh. Họ đang xử lý để họ cần để có thể thao tác chỉ các thành viên trường hợp này. Như trong ví dụ, tôi muốn hàm đó được gọi khi chỉ mục bản đồ tương ứng được truyền vào. Đơn giản, tôi muốn làm điều này: index [WM_CREATE] (hwnd, msg, lparam, wparam); và cách duy nhất tôi có thể nghĩ để làm điều đó là lưu trữ con trỏ hàm hoặc một cái gì đó tương tự ở đó. Tôi không thể làm con trỏ thực tế mặc dù vì nó phá vỡ thừa kế: ( – FatalCatharsis

+0

Bạn không thể sử dụng ['std :: mem_fun'] (http: //en.cppreference.com/w/cpp/utility/functional/mem_fn) thay thế? –

Trả lời

11

Tôi nghĩ vấn đề bạn đang gặp là một hàm thành viên đòi hỏi không chỉ là một con trỏ hàm, nhưng một con trỏ đến đối tượng gọi. Nói cách khác, các hàm thành viên có một đối số ngầm định bổ sung là con trỏ tới đối tượng gọi.

Để thiết lập một hàm thành viên cho một std :: chức năng, bạn cần phải sử dụng std :: ràng buộc như thế này:

std::function<void(int)> testFunc(std::bind(&A::func, this, _1)); 

này liên kết với con trỏ này của Một ví dụ hiện nay với chức năng vì vậy nó có con trỏ hàm và thể hiện đối tượng, là đủ thông tin để gọi đúng hàm. Đối số _1 cho biết đối số rõ ràng đầu tiên sẽ được cung cấp khi hàm được gọi.

+0

lỗi C2065: '_1': số nhận dạng không khai báo. Tôi gọi nó là 'HandlerIndex [WM_CREATE] = std :: function (std :: bind (& BasicWindow :: MsgCreate, this, _1))' – FatalCatharsis

+0

Bạn cần một trình giữ chỗ cho mọi đối số, do đó, nó sẽ là: 'std :: function (std :: bind (& BasicWindow :: MsgCreate, this, _1, _2, _3, _4))' –

+0

ah Gotcha, tôi sẽ thử nó khi tôi về nhà một chút. – FatalCatharsis

0

câu hỏi của tôi, là nó có thể tạo ra bất kỳ loại của đối tượng đó có thể gọi là một thành viên của một trường hợp cụ thể

Trong trường hợp này các thông tin duy nhất mà là mất tích là trong thực tế những gì ví dụ cụ thể đối tượng std::function nên sử dụng: &A::func không thể tự sử dụng (ví dụ (this->*&A::func)(0) sử dụng &A::func với ví dụ *this). Hãy thử:

std::function<void(int)> testFunc = std::bind(&A::func, this); 

(Hãy cẩn thận rằng std::bind(&A::func, *this)std::bind(&A::func, this) có ngữ nghĩa hơi khác nhau.)

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