todas - tipos de parametros en c++
¿Puedo enlazar a una función que toma argumentos predeterminados y luego llamarlo? (4)
¿Cómo puedo enlazar a una función que toma argumentos predeterminados, sin especificar los argumentos predeterminados y luego llamarlo sin ningún argumento?
void foo(int a, int b = 23) {
std::cout << a << " " << b << std::endl;
}
int main() {
auto f = std::bind(foo, 23, 34); // works
f();
auto g = std::bind(foo, 23); // doesn''t work
g();
using std::placeholders::_1;
auto h = std::bind(foo, 23, _1); // doesn''t work either
h();
}
Básicamente, cada vez que escribes foo(x)
el compilador lo traduce a foo(x, 23);
. Solo funciona si tiene una llamada directa con el nombre de la función. No puede, por ejemplo, asignar &foo
a un void(*)(int)
, porque la firma de la función es void(int, int)
. Los parámetros por defecto no juegan ningún papel en la firma. Y si lo asigna a una variable void(*)(int, int)
, la información sobre el parámetro predeterminado se pierde: no puede aprovechar el parámetro predeterminado a través de esa variable. std::bind
almacena un void(*)(int, int)
en algún lugar de sus entrañas y, por lo tanto, pierde la información del parámetro predeterminado.
No hay forma en C ++ de obtener el valor predeterminado de un parámetro desde fuera de la función, por lo que no puede proporcionar el valor predeterminado manualmente al vincular.
Creo que podrías simular el comportamiento que quieres usando un lambda.
Algo en la línea de esto:
auto g = [] (){ foo( 23 ); };
EDITAR: acaba de marcar y parece funcionar bien: http://ideone.com/SPSvi
Tengo dos soluciones:
1 - Puede sobrecargar foo () y hacer que llame al original con los valores predeterminados:
void foo(int a, int b)
{
std::cout << a << " " << b << std::endl;
}
inline void foo(int a)
{
foo(a, 23);
}
2 - Puede usar una variable estática como predeterminada y luego usarla en el proceso de enlace:
static int foo_default_b = 23;
void foo(int a, int b = foo_default_b)
{
std::cout << a << " " << b << std::endl;
}
auto g = std::bind(foo, 23, foo_default_b);
g();
Esta respuesta no está de acuerdo con la respuesta de R. Martinho Fernandes. De hecho, puede usar boost::bind
para enlazar con los parámetros predeterminados, solo necesita colocar marcadores de posición, así:
boost::bind<void (int, int)>(foo, _1, _2)(12);
Esto llamará foo(12, 23)
, como se esperaba. Aunque no probé este código específico, he hecho algo similar en mi código basado en la respuesta enlazada arriba, y funciona en gcc 4.8.5
.
Hmmm, acabo de notar que esto es una pregunta sobre std::bind
, no boost::bind
. No sé qué diferencias hay, si las hay.