2011-12-21 29 views
13
typedef bool (*Foo)(Foo a, Foo b); 

Làm thế nào để bạn khai báo một con trỏ hàm chấp nhận chính nó trong các tham số của nó?Một typedef đề cập đến chính nó

+1

Bạn không thể vì đó là một định nghĩa đệ quy không bao giờ có điểm dừng. –

+3

@SethCarnegie: đối số của bạn không hợp lệ. 'struct X {X * a; }; 'là khái niệm giống nhau, nhưng nó * được * cho phép. – ybungalobill

+1

@ybungalobill: Không, không phải là loại hàm chứa thông số của nó, loại lớp không chứa thành viên của nó. – Xeo

Trả lời

8

Gián tiếp:

struct Foo{ 
    typedef bool (*FooPtr)(Foo a, Foo b); 
    Foo(FooPtr p) 
     : p(p) 
    {} 

    bool operator()(Foo a, Foo b) const{ 
    return p(a,b); 
    } 

    FooPtr p; 
}; 

struct Bar{ 
    Bar(Foo f) 
     : some_callback(f) 
    {} 

    Foo some_callback; 
}; 

bool a_callback(Foo a, Foo b){ 
    return false; 
} 

int main() { 
    Bar b(a_callback); 
    b.some_callback(Foo(a_callback), Foo(a_callback)); 
} 

Không phải là tôi đã từng nhìn thấy bất kỳ sử dụng trong đó, như bạn có thể nhìn thấy từ ví dụ của tôi.

+1

Đó không phải là chính xác những gì được hỏi, nhưng nó có lẽ là xa như bạn có thể đi. –

+0

Tôi có thể tận dụng điều này, cảm ơn bạn Xeo. – Tergiver

2

Bạn không thể diễn tả điều này trong hệ thống kiểu. Mặc dù không có gì sai về cơ bản trong điều này, nó đơn giản hoá mọi thứ bằng cách loại bỏ các chu kỳ trong hệ thống kiểu. Nó mạnh mẽ nhắc tôi về Axiom of Foundation.

Những gì bạn có thể làm là vượt qua một con trỏ void và đúc nó vào loại bạn:

typedef bool (*Foo)(void* a, void* b); 

bool f(void* a, void* b) 
{ 
    return ((Foo)a)(a,b); 
} 
+1

Bạn không thể bỏ con trỏ 'void *' vào con trỏ hàm như thế. POSIX khuyến cáo sử dụng một cái gì đó như 'void * ptr; FunctionPtrType fptr; * (void **) (& fptr) = ptr; ', để tránh hành vi không xác định. –

+0

@ R.MartinhoFernandes: Bạn nói đúng là việc triển khai đã được xác định. Nhưng bạn có thể làm điều đó trên bất kỳ kiến ​​trúc von Neumann lành mạnh nào có 'void *' và các con trỏ hàm có cùng kích thước. – ybungalobill

+2

Bạn không thể truyền một cách có định dạng giữa 'void *' và các con trỏ hàm, cho dù bạn thêm vào bao nhiêu mức không giới hạn. Thay vào đó, hãy sử dụng một loại con trỏ hàm khác. –

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