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.

¿Por qué no se puede construir std::pair a partir de un tipo de función que se pasa por referencia?

Leí en algún lugar que el constructor de std::pair se pasa por valor (antes de c++11) porque si se pasa por referencia, std::pair no puede construirse a partir de un tipo de función de referencia. ¿Por qué?

//https://godbolt.org/z/5dMaG8E11

<h1>include <iostream></h1>

<h1>include <utility></h1>

void fun();

template <typename T>
void use(const T &)
{}

template <typename T, typename U>
std::pair<T, U> mp(const T & t, const U & u)
{
    return std::pair(t, u);
}

int main()
{
    use(::mp(fun, 3)); // failed
    use(std::make<em>pair(fun, 3)); // ok
}
<code>
</code>
/opt/compiler-explorer/gcc-10.3.0/lib/gcc/x86</em>64-linux-gnu/10.3.0/../../../../include/c++/10.3.0/bits/stl_pair.h:217:11: error: data member instantiated with function type 'void ()'
      _T1 first;                 ///< The first member
          ^
<source>:18:9: note: in instantiation of template class 'std::pair<void (), int>' requested here
    use(::mp(fun, 3)); // failed
        ^
<source>:13:12: error: no viable conversion from returned value of type 'pair<void (*)(), [...]>' to function return type 'pair<void (), [...]>'
    return std::pair(t, u);
           ^~~~~~~~~~~~~~~
<source>:18:11: note: in instantiation of function template specialization 'mp<void (), int>' requested here
    use(::mp(fun, 3)); // failed
          ^
Tags:  ,

Answer

  1. Avatar for davy.ai

    La razón por la que el constructor de std::pair pasa por valor antes de C++11 es porque si pasara por referencia, std::pair no podría construirse a partir de un tipo de función de referencia. Esto se debe a que los miembros de datos de std::pair deben ser predeterminadamente construibles, y un miembro de referencia a función no puede ser predeterminadamente construido. Por lo tanto, el constructor debe tomar parámetros por valor en lugar de por referencia para permitir la creación de objetos con miembros de datos que no pueden ser predeterminadamente construidos. A partir de C++11, sin embargo, las tuplas y pares ahora utilizan una reenviada perfecta para que los argumentos también puedan ser pasados por referencia.

Comments are closed.