Boost logo

Boost :

Subject: Re: [boost] [C++0x] Report from Frankfurt committee meeting
From: Andrew Sutton (andrew.n.sutton_at_[hidden])
Date: 2009-08-13 09:37:47

No, I'm thinking of using SFINAE generalized for expressions (note that this
requires a compiler which supports the feature, such as GCC 4.4+), that is
to say to put the expressions to check for directly in the signature of the
overload, be it with sizeof or decltype.

> For example, to check a variant of the Callable2<F, T1, T2> concept,
> template<int> struct dummy {};
> template<typename T> T& make();
> template<typename F, typename T1, typename T2>
> char callable2_impl(dummy<sizeof(
> typename F::result_type(
> make<F>()(
> make<T1>(),
> make<T2>()
> )
> )
> , 0)>*);
> template<typename F, typename T1, typename T2>
> char (&callable2_impl(...))[2];
> template<typename F, typename T1, typename T2>
> struct Callable2 : mpl::bool_<sizeof(callable2_impl<F, T1, T2>(0)) == 1>
> {
> };

That seems overly complicated. Why not...

template <typename...> failed call(...);
template <typename F, typename... Args>
auto call(F&& f, Args... args) -> decltype(f(args...));

template <typename F, typename... Args>
struct is_callable
  : not<is_same<decltype(call<F, Args...>(F(), Args()...)), failed>::type>
{ };

I'm waving my hands a bit since F() and Args() require everything to be
default constructible, but you can get around that with some clever
metaprogramming machinery and fake accessor functions.

It's worth pointing out that the this decltype trick works for pretty much
any possible query. Unfortunately, it fails (compilation) if f(args...) is
private, but hey... It works for most functions and functors, and that's
not bad.

Caveat: you probably need an SVN build of GCC to actually make that work
without internal compiler errors :)

Andrew Sutton

Boost list run by bdawes at, gregod at, cpdaniel at, john at