A vueltas con las plantillas

Publicado por laparca el 29 de mayo de 2009 — Publicado en Desarrollo

Ando haciendo pruebas últimamente con C++ y hay algo que ahora no soy capaz de hacer, que es que elija entre un método u otro dependiendo de si lo que se le pasa por parámetro es una función o un functor.

Concretamente tengo algo como esto:

template<typename T, typename Proxy = queue_proxy<T> >
class channel
{
public:
	template<typename Result>
	channel<Result, typename Proxy::template bind<Result>::type>
	operator>>(Result (&receiver)(T))
	{
		channel<Result, typename Proxy::template bind<Result>::type> out_channel;
		threads.push_back(new boost::thread(create_stream_channel_thread(*this, out_channel, receiver)));
		return channel<Result, typename Proxy::template bind<Result>::type>(out_channel);
	}
};

La idea es que este código permite hacer algo como lo siguiente:

int fac(int x)
{
	if(x < 1) return 1;
	return x * fac(x-1);
}
 
void show(int x)
{
	std::cout << x << std::endl;
}
 
/* some code here */
 
channel<int> ch;
 
/* Se redirige el canal a fac y la salida del factorial a show */
ch >> fac >> show;
 
/* more code here */

Sí, el código se parece mucho a Axum de Microsoft, que la idea es crear algo parecido para C++.

El caso es que el operador funciona bien cuando se pasan funciones, pero no funciona si le paso un functor, como podría ser el caso siguiente:

class functor
{
public:
	functor() {}
 
	int operator()(int a)
	{
		/* do something interesting */
	}
};
 
/* some code here */
 
channel<int> ch;
ch >> functor() >> show;

La cosa es que no sé como hacer para detectar que se me pasa un functor y qué parametros son los que tiene, aunque aún tengo que hacer alguna prueba más antes de dar por imposible la tarea.

4 comentarios »

Comentario by Fernando J. Pereda

operator()(int) debe ser ‘const’ en el functor. ¿O qué problema estás teniendo?

Posted on 31 de mayo de 2009 at 00:54

Comentario by laparca

El problema, concretamente, es que no puedo identificar si es o no un functor y en el caso de que sea un functor cual es el tipo de retorno del mismo.

Posted on 31 de mayo de 2009 at 01:35

Comentario by Fernando J. Pereda

La gracia de los templates es que no tengas que identificar si es un functor o no. Es decir, si en un objeto se puede aplicar el operador () pues se aplica, independientemente de si es una función o un functor. Ahora bien, el asunto del tipo de retorno no es tan simple… para eso creo que instanciar los templates lo cual es feo para el operador << y mucho menos elegante.

Posted on 31 de mayo de 2009 at 11:55

Comentario by laparca

En general, bibliotecas como boost lo que hacen es considerar que se le pasan functores y si no es un functor entonces tienes que hacer un bind de la función. Lo que yo estaba tratando de hacer es bucar un mecanismo que lo haga de forma transparente al programador.

Posted on 01 de junio de 2009 at 00:12

RSS feed para los comentarios de esta entrada. TrackBack URI

Deja un comentario