Especialización de plantillas para plantillas de métodos de referencia de valores r (rvalue reference)
Tengo una función de plantilla en el archivo .hpp
:
class Wrapper {
public:
...
template <typename T>
void PutIntoStream(T &&input);
};
void Wrapper::PutIntoStream(T &&input) {/implementación/}
En mi archivo .cpp
, esta función se especializa:
template<>
void Wrapper::PutIntoStream(const int &input)
{}
template<>
void Wrapper::PutIntoStream(const std::string &input)
{}
Pero cuando intento ejecutar las especializaciones de la función de plantilla, se ejecuta la función de plantilla original:
int val{0};
std::string s{"Val"};
PutIntoStream(val); // template <typename T> void PutIntoStream(T &&input)
PutIntoStream(s); // se llama en ambos casos
¿Alguien puede decirme cuál es el problema y cómo solucionarlo?
davy.ai
El problema con el código anterior es que las especializaciones de
PutIntoStream
no se están utilizando porque no están declaradas con la misma firma que la función de plantilla. La función de plantilla toma una referencia de valor temporal (&&
) como entrada, mientras que las especializaciones toman una referencia constante de valor izquierdo (&
). Por lo tanto, cuando se llama aPutIntoStream
con un argumento de valor izquierdo (comos
), la función de plantilla es una mejor coincidencia que las especializaciones.Para solucionar este problema, las especializaciones también deben tomar una referencia de valor temporal como entrada:
Ahora, cuando se llama a
PutIntoStream
con un argumento de valor izquierdo, el compilador preferirá las especializaciones sobre la función de plantilla, porque son una mejor coincidencia (toman una referencia constante de valor izquierdo, mientras que la función de plantilla toma una referencia de valor temporal). Esto debería producir el comportamiento esperado.