Boost logo

Boost :

From: Daniel Walker (daniel.j.walker_at_[hidden])
Date: 2008-06-03 12:19:10


On Tue, Jun 3, 2008 at 5:40 AM, Marco Costalba <mcostalba_at_[hidden]> wrote:
> Hi all,
>
> following code fails to compile:
>
> #include <boost/fusion/functional/invocation/invoke.hpp>
> #include <boost/fusion/include/make_vector.hpp>
>
> namespace fusion = boost::fusion;
>
> struct foo_t
> {
> int operator()() { return 1; }
> int operator()(int) { return 2; }
>
> template<typename>struct result { typedef int type; };
> };
>
> int main(int, char**)
> {
> foo_t foo;
>
> assert( fusion::invoke(foo, fusion::make_vector(3)) == 2 );
>
> assert( fusion::invoke(foo, fusion::make_vector()) == 1 ); // COMPILE
> ERROR HERE !
> }
>
> Boost is released 1.35, compiler gcc 4.2
>

This is actual a problem with the legacy/pre-C++0x result_of
heuristic. If you use boost trunk and gcc 4.3 with -std=c++0x, your
example will compile without error due to the new decltype-based
result_of. For C++98, the only solution is to specialize result_of for
nullary calls of your functor.

namespace boost {
template<> struct result_of<foo_t()> { typedef int type; };
}

The reason result_of couldn't deduce argument dependent return types
for nullary invocations in C++98 is that according to the heuristic
only the result_type member is checked for nullary calls, and for
non-nullary calls if the result_type is present, result<> is never
checked. So, you can't have both.

Daniel Walker


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk