2012-05-21 10 views
6

Tôi có một chức năng mà đòi hỏi một con trỏ hàm như là đối số:C++ chức năng ràng buộc để sử dụng như là đối số của hàm khác

int func(int a, int (*b)(int, int)) 
{ 
    return b(a,1); 
} 

Bây giờ tôi muốn sử dụng một chức năng nhất định mà có ba đối số trong hàm này:

int c(int, int, int) 
{ 
    // ... 
} 

làm thế nào tôi có thể ràng buộc đối số đầu tiên của c để tôi có thể làm:

int i = func(10, c_bound); 

Tôi đã nhìn vào số std::bind1st nhưng tôi không thể hình dung ra được. Nó không trả về một con trỏ hàm đúng không? Tôi hoàn toàn tự do để thích ứng với func vì vậy bất kỳ thay đổi nào về cách tiếp cận đều có thể thực hiện được. Althoug Tôi muốn cho người dùng mã của tôi có thể xác định c ...

lưu ý rằng ở trên là sự đơn giản hóa dữ dội của các chức năng thực tế mà tôi đang sử dụng.

Dự án đáng buồn yêu cầu C++98.

Trả lời

12

Bạn không thể làm điều đó. Bạn sẽ phải sửa đổi func để nhận đối tượng hàm trước. Một cái gì đó như:

int func(int a, std::function< int(int, int) > b) 
{ 
    return b(a, rand()); 
} 

Trong thực tế, không có nhu cầu b là một std::function, nó có thể được templated thay vì:

template< typename T > 
int func(int a, T b) 
{ 
    return b(a, rand()); 
} 

nhưng tôi sẽ gắn bó với phiên bản std::function cho rõ ràng và có phần ít đầu ra trình biên dịch phức tạp trên các lỗi.

Sau đó, bạn sẽ có thể làm điều gì đó như:

int i = func(10, std::bind(&c, _1, _2, some-value)); 

Lưu ý tất cả điều này là C++ 11, nhưng bạn có thể làm điều đó trong C++ 03 sử dụng Boost.

+2

mặc dù Tôi cần C++ 98 mã, câu trả lời này đã dễ dàng chuyển đổi thành tương đương tăng của nó. – romeovs

1

Vâng, nếu bạn biết tại thời gian biên dịch, những gì bạn có để ràng buộc c với, bạn có thể định nghĩa một hàm mới

int c_bound(int a, int b) { 
    return c(a,b,some_value); 
} 

Đó là rõ ràng không phải là một giải pháp chung chung nhưng có thể giải quyết vấn đề hiện tại của bạn. Nếu không thì giải pháp của K-ballo có vẻ là giải pháp chung dễ dàng nhất. Tuy nhiên, yêu cầu bạn có thể thay đổi chữ ký của func. Nếu bạn thực sự có API mà bạn không thể chạm vào chữ ký và bạn vẫn cần phải ràng buộc đối số VÀ nếu giải pháp trên không giải quyết được trường hợp cụ thể của bạn: (Thận trọng, quá mức cần thiết) Tôi luôn muốn sử dụng LLVM giải pháp dựa trên để biên dịch một hàm tại thời gian chạy và chuyển địa chỉ của nó trong các tình huống như vậy.

0

Bạn sẽ không thể sử dụng hàm đối số 3 làm hàm đối số 2; Chủ yếu là vì không có cách nào thực sự để xác định tham số thứ 3 sẽ làm gì.

Trong khi câu trả lời ở trên sẽ làm việc, đây là một tùy chọn:

Nếu một trong những tham số cho c(), được sử dụng trong vòng func, là hằng số, bạn có thể viết một hàm wrapper cho c(int, int, int):

int d(int a, int b) 
{ 
    return c(a, b, 0); //use a constant parameter 
} 

hoặc, nếu bạn có thể xác định tham số thứ 3 từ hai tham số nhất định, bạn cũng có thể thử:

int e(int a, int b) 
{ 
    int extra = 0; 
    ///Determine extra from a, and b 
    return c(a, b, c); 
}