c++ - compile - llvm clang for windows



¿Qué son las guías de deducción de plantillas y cuándo debemos usarlas? (1)

El estándar C ++ 17 presenta "guías de deducción de plantillas". Supongo que tienen algo que ver con la nueva deducción de argumentos de plantilla para constructores presentada en esta versión del estándar, pero aún no he visto una explicación simple, de estilo de preguntas frecuentes, de lo que son y para qué sirven.

  • ¿Qué son las guías de deducción de plantillas en C ++ 17?

  • ¿Por qué (y cuándo) los necesitamos?

  • ¿Cómo los declaro?


Las guías de deducción de plantillas son patrones asociados con una clase de plantilla que le dice al compilador cómo traducir un conjunto de parámetros (y sus tipos) en argumentos de plantilla.

El ejemplo más simple es el de std::vector y su constructor que toma un par iterador.

template<typename Iterator>
void func(Iterator first, Iterator last)
{
  vector v(first, last);
}

El compilador necesita averiguar qué tipo de T vector<T> será. Sabemos cuál es la respuesta; T debe ser typename std::iterator_traits<Iterator>::value_type . Pero, ¿cómo le decimos al compilador sin tener que escribir vector<typename std::iterator_traits<Iterator>::value_type> ?

Utiliza una guía de deducción:

template<typename Iterator> vector(Iterator b, Iterator e) -> 
    vector<typename std::iterator_traits<Iterator>::value_type>;

Esto le dice al compilador que, cuando llama a un constructor de vector que coincide con ese patrón, deducirá la especialización del vector usando el código a la derecha de -> .

Necesita guías cuando la deducción del tipo de los argumentos no se basa en el tipo de uno de esos argumentos. La inicialización de un vector desde una initializer_list usa explícitamente la T del vector , por lo que no necesita una guía.

El lado izquierdo no necesariamente especifica un constructor. La forma en que funciona es que, si usa la deducción de constructor de plantilla en un tipo, coincide con los argumentos que pasa contra todas las guías de deducción (los constructores reales de la plantilla primaria proporcionan guías implícitas). Si hay una coincidencia, la usa para determinar qué argumentos de plantilla proporcionar al tipo.

Pero una vez que se realiza esa deducción, una vez que el compilador descubre los parámetros de la plantilla para el tipo, la inicialización del objeto de ese tipo procede como si nada de eso sucediera. Es decir, la guía de deducción seleccionada no tiene que coincidir con el constructor seleccionado.

Esto también significa que puede usar guías con agregados e inicialización de agregados:

template<typename T>
struct Thingy
{
  T t;
};

Thingy(const char *) -> Thingy<std::string>;

Thingy thing{"A String"}; //thing.t is a `std::string`.

Por lo tanto, las guías de deducción solo se utilizan para determinar el tipo que se está inicializando. El proceso real de inicialización funciona exactamente como lo hizo antes, una vez que se ha tomado esa determinación.





template-deduction