Archivos mensuales: mayo 2009

A vueltas con las plantillas

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.