es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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?

Tags:  , , ,

Answer

  1. Avatar for 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 a PutIntoStream con un argumento de valor izquierdo (como s), 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:

    template <>
    void Wrapper::PutIntoStream(int &&input)
    {}
    
    template <>
    void Wrapper::PutIntoStream(std::string &&input)
    {}
    

    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.

Comments are closed.