Function traits


M

mlimber

Hi, I'm interested in detecting traits for function pointer,
std::functions, functors (including lambdas), and std::bind
expressions. At present I only care about nullary (i.e., no
parameters) and unary (i.e., one parameter) functions, and I want to
use these traits to wrap them up in a std::function object of the
appropriate type. Here's what I came up with for function pointers and
std::functions:

namespace nsDetail
{
class Dummy { Dummy(); };
}

template<class Fn> struct FnTraits;

template<class R>
struct FnTraits<R(*)()>
{
typedef nsDetail::Dummy ParamType;
typedef R ReturnType;
typedef R Signature();
static const bool IsNullary = true;
};

template<class R, class P>
struct FnTraits<R(*)(P)>
{
typedef P ParamType;
typedef R ReturnType;
typedef R Signature( P );
static const bool IsNullary = false;
};

template<class R>
struct FnTraits< std::function<R()> >
{
typedef nsDetail::Dummy ParamType;
typedef R ReturnType;
typedef R Signature();
static const bool IsNullary = true;
};

template<class R, class P>
struct FnTraits< std::function<R(P)> >
{
typedef P ParamType;
typedef R ReturnType;
typedef R Signature( P );
static const bool IsNullary = false;
};

Here's an example of how I use it -- I have some given functions that
accept std::function objects with two signatures:

void DoSomething( std::function<void()> ) { /*...*/ }
void DoSomething( std::function<void(int)> ) { /*...*/ }

I want to automate the conversion to std::function that is sometimes
required in the client code to resolve ambiguity. To do this, I'm
trying something like:

template<class Fn>
void Wrap( Fn fn )
{
// Wrap it up as a std::function and pass it in
DoSomething( std::function<
typename FnTraits<Fn>::Signature >( fn ) );
}

struct Functor
{
void operator()(int) const;
};

void Bar( int );

void Foo()
{
DoSomething( std::function<void()>( []{} ) ); // Ok
DoSomething( &Bar ); // ambiguous
DoSomething( []{} ); // ambiguous
DoSomething( Functor() ); // ambiguous
DoSomething( std::bind( Bar, 42 ) ); // ambiguous


Wrap( std::function<void()>( []{} ) ); // Ok
Wrap( &Bar ); // Ok
Wrap( []{} ); // error
Wrap( Functor() ); // error
Wrap( std::bind( Bar, 42 ) ); // error
}

How can I get general functors and bind expressions in my FnTraits
class? It doesn't have to be bulletproof in detecting every case, as
the uses for it are well-defined within my program. There will only be
one operator() per functor.

TIA! --M
 
Ad

Advertisements


Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top