studio programacion para móviles libros libro edición desarrollo curso aplicaciones c++ c++11 c++14 variadic-templates partial-specialization

c++ - programacion - ¿Cuáles son los 6 puntos en los paquetes de parámetros de plantilla?



manual de programacion android pdf (2)

¿Por qué utiliza libstdc++ ... ... en su implementación de is_function ? Si revisamos la sección de referencia de cpp para std :: is_function , da una implementación de ejemplo y dice para el primer ... ... caso:

// specialization for variadic functions such as std::printf template<class Ret, class... Args> struct is_function<Ret(Args......)> : std::true_type {};

por lo que necesitamos el segundo conjunto de ... para que coincida con una función variadic como printf :

Comma optional as per 8.3.5 [dcl.fct] | v Ret(Args... ...) ^ ^ | | Match a function with a variable number of arguments | and the function is a variadic function

Tenga en cuenta que tenemos funciones como fprintf que dos argumentos antes de los términos variadic y también necesitamos coincidir con ellos. De hecho, si usamos esa implementación e intentamos hacer coincidir printf sin la especialización ... ... entonces no podemos verla en vivo .

Este rincón del lenguaje está cubierto en los seis puntos de este post de C ++ 11 :

El otro día estuve andando por ahí y descubrí esta pequeña y agradable rareza:

template <typename... Args> void foo(Args......);

Como resultado, ...... puede ser totalmente válido C ++ 11. Esto es lo que sucede cuando la compatibilidad hacia atrás se mezcla con el nuevo picor.

// Todos estos son equivalentes.

template <typename... Args> void foo1(Args......); template <typename... Args> void foo2(Args... ...); template <typename... Args> void foo3(Args..., ...);

Esperemos que el último muestre lo que está pasando aquí. [...]

¿Por qué es este valild? Podemos ver que , ... es sinónimo de ... del borrador de la sección 8.3.5 [dcl.fct] de la norma C ++ 11 que tiene la siguiente gramática:

parameter-declaration-clause: parameter-declaration-listopt...opt parameter-declaration-list , ...

y dice:

[...] Donde sintácticamente correcto y donde "..." no es parte de un declarador abstracto, ", ..." es sinónimo de "...". [...]

Mientras miraba this pregunta, me encontré en el sitio de referencia de cpp donde noté una sintaxis extraña y nueva para mí:

template<class Ret, class... Args> struct is_function<Ret(Args......)volatile &&> : std::true_type {};

Sí, 6 puntos! Inicialmente, pensé que era un error tipográfico, pero después de revisar la source libstdc ++ nuevamente, por ejemplo, estaba en la línea 444:

template<typename _Res, typename... _ArgTypes> struct is_function<_Res(_ArgTypes......) volatile &&> : public true_type { };

¿Es esta una sintaxis válida? Dot dot dot, ¿se utilizan para empaquetar y desempaquetar paquetes de parámetros? ¿Qué hacen 6 puntos?


En este caso, los dos son para diferentes propósitos. El primero es para la expansión del paquete de parámetros y el segundo para las listas de argumentos variables. Esa declaración en particular es para manejar funciones que toman algunos parámetros regulares más una lista de argumentos variables.

La diferencia es entre la variabilidad en tiempo de ejecución y en tiempo de compilación. Una función que toma un número variable de argumentos en tiempo de ejecución es especial. Es una función única que puede manejar un número variable de argumentos de la persona que llama:

void f(int x,...) // equivalent to void f(int x ...) { // Do some run-time logic here to determine what to // do with parameters after x. }

Esto es distinto de la noción de que queremos poder tener una plantilla que use una variedad de funciones con varios parámetros que se conocen en el momento de la compilación. Por ejemplo, podríamos definir una plantilla de función que lleve un puntero a una función y permita que el número y los tipos de los argumentos varíen:

template <typename... Args> void g(void (*function_ptr)(Args...)) { // We can do logic here to call function_ptr with the proper // number of arguments. }

Teniendo en cuenta estas funciones:

void f1(int); void f2(int,float);

Puedes llamar a g con cualquiera de ellos:

g(f1); // fine g(f2); // also fine

sin embargo

g(f); // error

El compilador no sabría qué usar para el paquete de parámetros Args en g .