Mọi trường hợp của sự kỳ lạ đó được ghép nối với một trường hợp của một dấu chấm lửng đơn thông thường.
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......)>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes...) const>
{ typedef _Res result_type; };
template<typename _Res, typename... _ArgTypes>
struct _Weak_result_type_impl<_Res(_ArgTypes......) const>
{ typedef _Res result_type; };
Tôi đoán rằng dấu chấm lửng kép có ý nghĩa tương tự với _ArgTypes..., ...
, tức là một mở rộng mẫu đa dạng theo sau là danh sách các varargs kiểu C.
Đây là một bài kiểm tra hỗ trợ lý thuyết đó… Tôi nghĩ chúng ta có một người chiến thắng mới cho toán tử giả tồi nhất từ trước đến nay.
Chỉnh sửa: Điều này có vẻ là phù hợp. §8.3.5 / 3 mô tả một cách để tạo danh sách tham số là
tham số-khai báo-danh sách lựa chọn ... lựa chọn
Vì vậy, dấu ba chấm kép được hình thành bởi một danh sách khai báo tham số kết thúc bằng một gói tham số, theo sau là một dấu chấm lửng khác.
Dấu phẩy hoàn toàn là tùy chọn; §8.3.5 / 4 không nói
Nếu đúng về mặt cú pháp và “...” không phải là một phần của bộ khai báo trừu tượng, thì “, ...” đồng nghĩa với “...”.
Đây là bên trong một bộ khai báo trừu tượng, [sửa] nhưng Johannes nói rõ rằng họ đang đề cập đến một bộ khai báo trừu tượng trong một khai báo tham số. Tôi tự hỏi tại sao họ không nói "một phần của khai báo tham số" và tại sao câu đó không chỉ là một ghi chú thông tin…
Hơn nữa, va_begin()
trong <cstdarg>
yêu cầu một tham số trước danh sách varargs, vì vậy nguyên mẫu f(...)
được C ++ cho phép cụ thể là vô dụng. Tham chiếu chéo với C99, nó là bất hợp pháp ở đồng bằng C. Vì vậy, điều này là kỳ lạ nhất.
Chú thích sử dụng
Theo yêu cầu, đây là minh họa về dấu chấm lửng kép:
#include <cstdio>
#include <string>
template< typename T >
T const &printf_helper( T const &x )
{ return x; }
char const *printf_helper( std::string const &x )
{ return x.c_str(); }
template< typename ... Req, typename ... Given >
int wrap_printf( int (*fn)( Req... ... ), Given ... args ) {
return fn( printf_helper( args ) ... );
}
int main() {
wrap_printf( &std::printf, "Hello %s\n", std::string( "world!" ) );
wrap_printf( &std::fprintf, stderr, std::string( "Error %d" ), 5 );
}
...
theo sau bởi...
.