Nói chung, việc sử dụng tính năng mẫu C++ 11 variadic có chức năng yêu cầu đối số hàm dựa trên variadic là đối số cuối cùng trong danh sách đối số hàm. Có một ngoại lệ; chúng là các đối số từ đầu đến cuối nếu có các đối số variadic C-level, mà phải chết cuối cùng.Làm thế nào các đối số C++ và C variadic có thể được sử dụng cùng nhau?
template < typename ...Args >
int super_printf(Something x, Args &&...a, ...);
Đôi khi tôi nghĩ ngẫu nhiên về C++ và tôi tự hỏi làm thế nào một chức năng như vậy có thể được triển khai. Lần đầu tiên tôi nghĩ về việc bóc lột đệ quy thông thường từ a, sau đó tôi nhớ rằng các varargs cấp C không xếp tầng. Tôi phải biến chúng thành một va_list dứt khoát ngay lập tức.
template < typename ...Args >
int super_vaprintf(Something x, std::va_list &aa, Args &&...a);
// Note that "aa" is passed by reference.
template < typename ...Args >
int super_printf(Something x, Args &&...a, ...)
{
std::va_list args2;
int result;
va_start(args2, XXX); // (A)
try {
result = super_vaprintf(x, args2, std::forward<Args>(a)...);
} catch (...) {
va_end(args2); // (1)
throw;
}
va_end(args2); // (2)
return result;
// Can (1) and (2) be compacted with RAII using a custom deleter lambda
// in std::unique_ptr or something? Remember that "va_end" is a macro!
}
Việc lột bỏ thông thường C++ variadic xảy ra trong cuộc gọi super_vaprintf
. Tại dòng (A), những gì xảy ra ở vị trí của XXX
, "a" hoặc "a ..."? Điều gì sẽ xảy ra nếu a trống, thay vào đó, x sẽ chuyển sang đó? Nếu câu hỏi cuối cùng đó là đúng, chúng tôi sẽ bị hỏng nếu không có x; rằng không có đối số bên cạnh những cái variadic? (Và nếu đó là sự thật, làm thế nào để chúng ta conditionalize mã để sử dụng x khi một là trống rỗng, và một khác?)
...
Tôi chỉ nhìn bản sao của tôi về C++ 11 tiêu chuẩn cho bất kỳ hỗ trợ ở đây. Dường như không có gì. Điều này sẽ nhắc một yêu cầu cho ủy ban C++ quay trở lại để sửa lỗi này, nhưng tôi không chắc rằng có bất kỳ cách nào một hàm như vậy có thể được gọi mà không có biến thể C++ lấy mọi thứ. Liệu tôi có sai; có thể thực hiện một cuộc gọi hàm để sử dụng cả hai biến thể C++ và C? Hoặc là chỉ pha trộn hữu ích cho các khai báo, về các thủ thuật instantiation Stupid (Template)?
Chỉ sau khi đăng bài này, tôi nhận ra rằng có thể một cái gì đó như "' super_printf (Cái gì {}, 1, 2, 3, 4) '" có thể bắt buộc một số đối số là cấp C ("3" và "4" trong trường hợp này). –
CTMacUser
chúng là trực giao, vì c và hoạt động ở thời gian chạy, và C++ Các mẫu variadic làm việc tại thời gian biên dịch –
@CTMacUser: vâng, điều đó sẽ hoạt động. Câu hỏi vẫn còn hữu ích như thế nào, và tôi sẽ nói trong metaprogramming nó có thể . có thể bạn có thể tìm thấy nhiều thông tin chi tiết hơn trong việc đọc các đề xuất mẫu của variadic, họ có thể cho biết lý do tại sao điều này là có thể. – PlasmaHH