xem xét mã này:generic function pointer viên làm mẫu tham số
#include <iostream>
using namespace std;
class hello{
public:
void f(){
cout<<"f"<<endl;
}
virtual void ff(){
cout<<"ff"<<endl;
}
};
#define call_mem_fn(object, ptr) ((object).*(ptr))
template<R (C::*ptr_to_mem)(Args...)> void proxycall(C& obj){
cout<<"hello"<<endl;
call_mem_fn(obj, ptr_to_mem)();
}
int main(){
hello obj;
proxycall<&hello::f>(obj);
}
Tất nhiên điều này sẽ không biên dịch tại dòng 16, bởi vì trình biên dịch không biết những gì R
, C
và Args
, đang có. Nhưng có một vấn đề khác: nếu một cố gắng để xác định các tham số mẫu ngay trước ptr_to_mem
, ông chạy vào tình huống xấu này:
template<typename R, typename C, typename... Args, R (C::*ptr_to_mem)(Args...)>
// ^variadic template, but not as last parameter!
void proxycall(C& obj){
cout<<"hello"<<endl;
call_mem_fn(obj, ptr_to_mem)();
}
int main(){
hello obj;
proxycall<void, hello, &hello::f>(obj);
}
Đáng ngạc nhiên, g ++ không phàn nàn về Args
không phải là tham số cuối cùng trong danh sách mẫu, nhưng dù sao nó không thể liên kết proxycall
với chức năng mẫu phù hợp, và chỉ cần lưu ý rằng đó là một ứng viên có thể.
Bất kỳ giải pháp nào? Phương pháp cuối cùng của tôi là chuyển con trỏ hàm thành viên làm đối số, nhưng nếu tôi có thể chuyển nó thành tham số mẫu, nó sẽ phù hợp hơn với phần còn lại của mã của tôi.
EDIT: như một số đã chỉ ra, ví dụ có vẻ vô nghĩa vì proxycall sẽ không vượt qua bất kỳ đối số nào. Điều này là không đúng trong mã thực tế tôi đang làm việc trên: các đối số được lấy với một số thủ thuật mẫu từ một ngăn xếp Lua. Nhưng phần mã đó không liên quan đến câu hỏi, và khá dài, vì vậy tôi sẽ không dán nó ở đây.
Dường như với tôi rằng bạn không thực sự cần các tham số mẫu của vectơ trong trường hợp này. 'proxycall()' sẽ không chuyển bất kỳ đối số nào tới lời gọi con trỏ hàm thành viên, vì vậy việc sử dụng các tham số mẫu của Denisdic xuất hiện để làm cho vấn đề khó khăn hơn nó cần. –
Điều này không có ý nghĩa. "Call_mem_fn" #define của bạn không thực sự cung cấp thông số. Vì vậy, nó sẽ không hoạt động nếu Args là bất cứ điều gì nhưng trống rỗng. Vì vậy, làm thế nào để bạn mong đợi điều này để thực sự hoạt động? –
Mã trong câu hỏi chỉ là một ví dụ. Mã thực tế sẽ xử lý các hàm với một số đối số tùy ý, và chúng sẽ được lấy ra từ một nơi khác (cụ thể là một ngăn xếp Lua). Mã keo siêu lập trình tải các đối số đã hoạt động, tôi sẽ không dán nó ở đây vì nó dài. –