Jakie jest znaczenie "... ... " tokena? tj. operator podwójnej elipsy na pakiecie parametrów
Przeglądając aktualną implementację GCC nowych nagłówków C++11, natknąłem się na "......"token. Możesz sprawdzić, czy poniższy kod kompiluje fine [poprzez ideone.com].
template <typename T>
struct X
{ /* ... */ };
template <typename T, typename ... U>
struct X<T(U......)> // this line is the important one
{ /* ... */ };
Więc, jakie jest znaczenie tego żetonu?
Edit: wygląda tak przycięte "......"w pytaniu tytuł do"...", Naprawdę miałem na myśli "......" . :)
2 answers
Każdy przypadek tej dziwności jest sparowany z przypadkiem regularnej pojedynczej elipsy.
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; };
Domyślam się, że Podwójna elipsa jest podobna w znaczeniu do _ArgTypes..., ...
, tzn. zmiennego rozszerzenia szablonu, po którym następuje lista varargs w stylu C.
Oto test potwierdzający tę teorię ... myślę, że mamy nowego Zwycięzcę najgorszego pseudo-operatora.
Edit: to wydaje się być zgodne. §8.3.5 / 3 opisuje jeden sposób tworzenia listy parametrów as
Parameter-declaration-listopt ... opt
Tak więc Podwójna elipsa jest tworzona przez parametr-deklarację-listę kończącą się pakietem parametrów, po którym następuje kolejna elipsa.
Przecinek jest czysto opcjonalny; §8.3.5/4 mówi
Gdzie poprawne składniowo i gdzie "..."nie jest częścią abstract-declarator,",..."jest synonimem "...".
To jest w obrębie abstract-declarator, [edytuj] ale Johannes zwraca uwagę, że odwołują się do deklaratora abstrakcyjnego w parametrze-deklaracji. Zastanawiam się, dlaczego nie powiedzieli "część parametru-deklaracji" i dlaczego to zdanie nie jest tylko notatką informacyjną ...
Ponadto, va_begin()
w <cstdarg>
wymaga parametru przed listą varargs, więc prototyp f(...)
specjalnie dozwolony przez C++ jest bezużyteczny. Porównywanie z C99, jest nielegalne w prostym C. Więc jest to najbardziej dziwne.
Uwaga dotycząca użytkowania
Na życzenie, oto demonstracja podwójnej elipsy:
#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 );
}
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-04-12 12:49:40
Na vs2015 separacja przecinków jest niezbędna w wersji szablonu:
template <typename T, typename ... U>
struct X<T(U...,...)> {};// this line is the important one
Przykładowa instancja to:
X<int(int...)> my_va_func;
Pozdrawiam, FM.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-05-26 17:40:50