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.

¿Bajo qué condiciones std::forward y static_cast son equivalentes?

El enlace http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0644r1.html dice:

Hay dos formas de reenviar una variable: se puede usar std::forward o se puede usar static_cast directamente (como lo hace el operador de reenvío de esta propuesta):

template <class x,="" class="" y="">
decltype(auto) foo(X&& x, Y&& y) {
    return std::forward<x>(x)(std::forward<y>(y));    // con std::forward
    return static_cast<x&&>(x)(static_cast<y&&>(y));  // con static_cast, exactamente equivalente
}

¿Se aplica “exactamente equivalente” porque X e Y son parámetros de plantilla y, por lo tanto, X&& e Y&& son referencias de reenvío? ¿O por alguna otra razón?

Supongo que no siempre se aplica, porque si lo hiciera:
1. Esperaría que la documentación de std::forward lo mencionara, como lo hace la de std::move;
2. No habría motivo para el aumento del 14% en la velocidad de compilación al reemplazar uno con el otro.

Mi mejor suposición actual es que:
1. std::forward no se compila en algunos casos en los que static_cast sí se compila;
2. Pero no viceversa: si std::forward se compila, también lo hace static_cast;
3. Si se compila, ambos tienen el mismo resultado.

Pero estoy lejos de estar seguro de que sea correcto.</y&&></x&&>

Tags:  , ,

Answer

  1. Avatar for davy.ai

    La afirmación “exáctamente equivalente” se aplica porque X e Y son parámetros de plantilla y por lo tanto X&& e Y&& son referencias hacia adelante. Cuando X e Y son referencias hacia adelante, static_cast<x&&>(x) y std::forward<x>(x) son exactamente equivalentes.

    No siempre es el caso de que std::forward y static_cast sean exactamente equivalentes. Por ejemplo, si X no es una referencia hacia adelante, entonces std::forward<x>(x) no se compilará, pero static_cast<x&&>(x) sí se compilará. Del mismo modo, si X es una referencia de valor izquierdo, entonces std::forward<x>(x) producirá una referencia de valor izquierdo, mientras que static_cast<x&&>(x) producirá una referencia de valor derecho.

    Por lo tanto, es importante usar el mecanismo de reenvío correcto dependiendo del tipo de los argumentos que se están reenviando. Si los argumentos son referencias hacia adelante, tanto std::forward como static_cast funcionarán, y producirán exactamente el mismo resultado.</x&&></x&&></x&&>

Comments are closed.