Tôi đang cố lưu trữ một std::tuple
số lượng giá trị khác nhau, sau này sẽ được sử dụng làm đối số cho một cuộc gọi đến một con trỏ hàm khớp với các loại được lưu trữ.
Tôi đã tạo một ví dụ đơn giản hóa cho thấy vấn đề tôi đang đấu tranh để giải quyết:
#include <iostream>
#include <tuple>
void f(int a, double b, void* c) {
std::cout << a << ":" << b << ":" << c << std::endl;
}
template <typename ...Args>
struct save_it_for_later {
std::tuple<Args...> params;
void (*func)(Args...);
void delayed_dispatch() {
// How can I "unpack" params to call func?
func(std::get<0>(params), std::get<1>(params), std::get<2>(params));
// But I *really* don't want to write 20 versions of dispatch so I'd rather
// write something like:
func(params...); // Not legal
}
};
int main() {
int a=666;
double b = -1.234;
void *c = NULL;
save_it_for_later<int,double,void*> saved = {
std::tuple<int,double,void*>(a,b,c), f};
saved.delayed_dispatch();
}
Thông thường đối với các vấn đề liên quan đến std::tuple
hoặc các mẫu biến đổi, tôi sẽ viết một mẫu khác template <typename Head, typename ...Tail>
để đánh giá đệ quy tất cả các loại từng cái một, nhưng tôi không thể thấy cách thực hiện điều đó để gửi một lệnh gọi hàm.
Động lực thực sự cho việc này có phần phức tạp hơn và dù sao nó cũng chỉ là một bài tập học tập. Bạn có thể giả sử rằng tôi đã trao bộ dữ liệu bằng hợp đồng từ một giao diện khác, vì vậy không thể thay đổi nhưng mong muốn giải nén nó thành một cuộc gọi chức năng là của tôi. Điều này loại trừ việc sử dụng std::bind
như một cách rẻ tiền để vượt qua vấn đề tiềm ẩn.
Cách tốt nhất để gửi cuộc gọi bằng cách sử dụng std::tuple
hoặc cách khác tốt hơn để đạt được cùng một kết quả ròng là lưu trữ / chuyển tiếp một số giá trị và con trỏ hàm cho đến một điểm tương lai tùy ý?
auto saved = std::bind(f, a, b, c);
... sau đó chỉ cần gọisaved()
?