Si tengo una función de plantilla como

template<typename T>
void doSomething(const T arg) {.....}

Entonces no sé de antemano si T es un int simple o si es una estructura enorme. Si es un int, pasar por valor tiene sentido, mientras que la estructura debe pasarse por referencia.

¿Cómo diseño una función de plantilla que funcione con sensatez con ambos tipos de argumentos?

1
JoeTaicoon 12 ago. 2016 a las 10:42

2 respuestas

La mejor respuesta

La biblioteca boost::call_traits tiene varios ayudantes para Cosas como esta. En particular, call_traits<T>::param_type

Define un tipo que representa la "mejor" forma de pasar un parámetro de tipo T a una función.

Lo usas así:

template<typename T>
void doSomething(typename boost::call_traits<T>::param_type arg) {.....}

Básicamente funciona especializando la clase para casos especiales. Entonces, por ejemplo, su caso int de la pregunta está (indirectamente) especializado en int (y ​​no int &).

2
Ami Tavory 12 ago. 2016 a las 07:49

Su pregunta es un problema XY. Estás pidiendo una solución a un problema que solo surge de una mala 'solución' a otro problema. Entonces, aquí decido responder a su problema inicial.

Dado que la función de su plantilla seguramente tendrá que ser inline, la mayoría de los compiladores optimizarán la llamada a la función y con ella su problema. Por lo tanto, puede que en realidad no importe lo que use, pero T const&arg es el más conservador.

Entonces, antes de 'resolver' este problema, debe probar si existe alguna diferencia medible entre las dos opciones para un int simple (con la optimización del estilo de producción activada).

1
Community 20 mar. 2017 a las 10:29