Diferencia entre std::decay y std::remove_reference

Resuelto Nex' asked hace 6 años • 2 respuestas

Cuando hago metaprogramación de plantillas en C++, a menudo me encuentro con algo como lo siguiente:

template <typename T>
S<T> make_wrapper(T&& t) { return S<T>(std::forward<T>(t)); }

Sé que debería usar algo como std::decayel tipo de devolución, pero ¿por qué no std::remove_referencefuncionaría tan bien? ¿Cuál es la diferencia aquí? Qué pasa std::remove_cvref?

Nex' avatar Dec 18 '17 22:12 Nex'
Aceptado

Considere por ejemplo

#include <type_traits>

int main()
{
    static_assert(std::is_same_v<
        std::decay_t<const int&>, 
        std::remove_reference_t<const int&>
    >); // int != const int
}

std::decayeliminará cualquier calificador cv, remove_referenceno lo hará. Simplemente eliminará la parte de "referencia" del tipo.

De la referencia :

Aplica conversiones implícitas de valor a valor, matriz a puntero y función a puntero al tipo T, elimina calificadores cv y define el tipo resultante como el tipo de miembro typedef.

Por lo tanto, std::decayrealizará muchas más conversiones de tipos que std::remove_reference.

También hay más modificadores de tipo para aplicaciones más matizadas que solo realizarán partes seleccionadas del conjunto de transformaciones posibles decay, como remove_cv, remove_volatileo, en C++20, remove_cvref.

Jodocus avatar Dec 18 '2017 15:12 Jodocus