c++ templates template-deduction function-templates argument-deduction

c++ - El argumento predeterminado de la plantilla pierde su tipo de referencia



templates template-deduction (2)

Para foo<int>(a) , ARG_T se deduce de a , y no se toma del argumento de plantilla predeterminado. Como es un parámetro de función por valor y a es una expresión de tipo int , se deduce como int .

En general, los argumentos de plantilla predeterminados no se usan cuando la deducción de argumentos de plantilla puede descubrir cuál es el argumento.

Pero podemos forzar el uso del argumento predeterminado introduciendo un contexto no deducido para el parámetro de función. Por ejemplo:

template <class T, class ARG_T = T&> T foo(std::enable_if_t<true, ARG_T> v1){ //... }

O la utilidad C ++ 20 type_identity , como lo demuestra la otra respuesta.

Considerar

#include <iostream> #include <type_traits> template <class T, class ARG_T = T&> T foo(ARG_T v){ return std::is_reference<decltype(v)>::value; } int main() { int a = 1; std::cout << foo<int>(a) << ''/n''; std::cout << foo<int, int&>(a) << ''/n''; }

Esperaría que la salida sea 1 en ambos casos. Pero en el primer caso es 0: coherente con la class ARG_T = T predeterminada class ARG_T = T lugar de la class ARG_T = T& .

¿Qué me estoy perdiendo?


ARG_T detener la deducción de argumentos de plantilla para ARG_T del argumento de función v , (con la ayuda de std::type_identity , que podría usarse para excluir argumentos específicos de la deducción); De lo contrario, no se utilizará el argumento de plantilla predeterminado. p.ej

template <class T, class ARG_T = T&> T foo(std::type_identity_t<ARG_T> v){ return std::is_reference<decltype(v)>::value; }

LIVE

Por cierto: si su compilador no admite std::type_identity (desde C ++ 20), puede hacer el suyo.

template<typename T> struct type_identity { typedef T type; }; template< class T > using type_identity_t = typename type_identity<T>::type;