> > > As to your suggestion: I don't think you can overload connect()
> > > specifically for a lambda with a specific signature ?
> >
> > No, but it's possible to check at compile time whether a function
> > object is callable with a particular set of argument types, and
> > dispatch to different implementations based on the result. If you
> > think this is a reasonable approach, I'm happy to write some
> > proof-of-concept code to demonstrate.
> >
> > > As to how you can make it work: you can use std::bind() to bind away
> > > the argument. See for example the second example at :
> > > http://www.webtoolkit.eu/widgets/forms/push-button
> >
> > I think it would be nice if Wt did this adaptation step.
>
> Certainly, and I would appreciate a proof-of-concept ?
>
> This would mean that you can make it entirely an implementation detail
> of connect(F f) with f a function object?
Yep. See the attached code file, which declares a template function
called 'call_with_zero_or_one_args' which takes a function object,
and calls it with an argument of a specific type if it can, or with
no arguments otherwise.
I am proposing that 'connect(F f)' be implemented in a similar way.
The implementation uses the C++11 features 'decltype' and 'extended
SFINAE', so it would need to be ifdef-ed out on compilers that don't
support these (and the current implementation used instead).
Boost.Config conveniently provides macros for testing the presence
of each C++11 feature [1], so the guard can be something like:
!defined(BOOST_NO_CXX11_DECLTYPE) && !defined(BOOST_NO_SFINAE_EXPR)
I don't know whether a C++03 implementation is possible; decltype
might be replaceable with BOOST_TYPEOF but I don't know whether the
extended SFINAE can be replaced by something else. In practice, a
C++11 implementation should be fine since the aim is to improve
support for C++11 lambdas.
Regards,
Nate
[1]
http://www.boost.org/doc/libs/1_53_0/libs/config/doc/html/boost_config/boost_macro_reference.html#boost_config.boost_macro_reference.macros_that_describe_c__11_features_not_supported
// PART 1 - A metafunction that tests whether a function object
// is callable with a single argument of a specified type.
#include <boost/mpl/if.hpp>
#include <boost/utility/declval.hpp>
template <typename F, typename Arg>
struct is_callable_with_argument
{
typedef char (&no) [1];
typedef char (&yes)[2];
template <typename T> struct dummy;
template <typename T>
static yes check(dummy<decltype(boost::declval<T>()(boost::declval<Arg>()))>*);
template <typename T>
static no check(...);
static const bool value = (sizeof(check<F>(0)) == sizeof(yes));
};
// PART 2 - A metafunction that converts the result of is_callable_with_argument
// to a type tag.
struct zero_args_tag {};
struct one_arg_tag {};
template <typename F, typename Arg>
struct callable_with_argument_tag
{
typedef typename boost::mpl::if_<is_callable_with_argument<F, Arg>,
one_arg_tag,
zero_args_tag>::type type;
};
// PART 3 - A function that uses callable_with_argument_tag to dispatch
// to a different implementation based on whether the function
// object is callable with a specific argument type.
struct ArgType {}; // the specific argument type
// implementation for a zero-argument function object
template <typename F>
void call_with_zero_or_one_args_impl(const F& f, zero_args_tag)
{
f();
}
// implementation for a one-argument function object
template <typename F>
void call_with_zero_or_one_args_impl(const F& f, one_arg_tag)
{
ArgType arg;
f(arg);
}
// dispatching code
template <typename F>
void call_with_zero_or_one_args(const F& f)
{
call_with_zero_or_one_args_impl(f, typename callable_with_argument_tag<F, ArgType>::type());
}
// PART 4 - Example usages of call_with_zero_or_one_args.
#include <boost/bind.hpp>
void zero_args() {}
void one_arg(ArgType) {}
struct zero_args_t
{
void operator()() const {}
};
struct one_arg_t
{
void operator()(ArgType) const {}
};
struct foo
{
void bar1() const {}
void bar2(ArgType) const {}
};
int main()
{
call_with_zero_or_one_args([]{});
call_with_zero_or_one_args([](ArgType){});
call_with_zero_or_one_args(&zero_args);
call_with_zero_or_one_args(&one_arg);
call_with_zero_or_one_args(zero_args_t());
call_with_zero_or_one_args(one_arg_t());
foo f;
call_with_zero_or_one_args(boost::bind(&foo::bar1, f));
call_with_zero_or_one_args(boost::bind(&foo::bar2, f, _1));
}
------------------------------------------------------------------------------
Own the Future-Intel® Level Up Game Demo Contest 2013
Rise to greatness in Intel's independent game demo contest.
Compete for recognition, cash, and the chance to get your game
on Steam. $5K grand prize plus 10 genre and skill prizes.
Submit your demo by 6/6/13. http://p.sf.net/sfu/intel_levelupd2d
_______________________________________________
witty-interest mailing list
witty-interest@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/witty-interest