Boost logo

Boost Users :

Subject: Re: [Boost-users] [fusion] trouble with transform
From: Nathan Ridge (zeratul976_at_[hidden])
Date: 2011-11-12 01:57:00


> Hi,
>
> I have code similar to the following snippet:
>
> #include <boost/fusion/container/list/list.hpp>
> #include <boost/fusion/container/list/convert.hpp>
> #include <boost/fusion/container/generation/make_list.hpp>
> #include <boost/fusion/algorithm/transformation/transform.hpp>
> namespace fusion=boost::fusion;
>
> template<typename T>
> class A {
> public:
> struct B {};
>
> B make_b() const { return B(); }
> };
>
> template<typename T>
> A<T>
> make_a( T const& )
> {
> return A<T>();
> }
>
> struct make_b {
> template<typename Sig> struct result;
>
> template <typename DS>
> struct result<make_b(DS const&)>
> {
> typedef typename DS::B type;
> };
>
> template <typename T>
> typename T::B
> operator()(T const& t) const { return t.make_b(); }
> };
>
> int
> main()
> {
> namespace fusion=boost::fusion;
>
> fusion::as_list( fusion::transform(
> fusion::make_list( make_a( 1. ), make_a( 1 ) ),
> make_b() ) );
>
> return 0;
> }
>
> it fails to compile with an error like this:
>
> ... rather long context here
> ..\..\../boost/utility/result_of.hpp:83:1: error:
> invalid use of incomplete type ‘struct make_b::result<make_b(A<double>)>’
> test.cpp:27:35: error: declaration of ‘struct make_b::result<make_b(A<double>)>’
>
> What am I doing wrong?

You need to add a specialization result_of<make_b(DS)>, in addition to
result_of<make_b(DS const&)>:

template <typename DS>
struct result<make_b(DS)>
{
    typedef typename DS::B type;
};

You need this because your operator() can be called with either a argument of
type T, or an argument of type T const&. You don't need two versions of your
operator(), because T is implicitly convertible to T const&, but the result<>
template is instantiated with the exact argument type without any conversions
being performed.

This is subtle issue, I explain it in more detail here [1]. Thank goodness
in C++11 we will be able to avoid it by using decltype.

Regards,
Nate

[1] http://lists.boost.org/boost-users/2011/07/69684.php
                                               


Boost-users list run by williamkempf at hotmail.com, kalb at libertysoft.com, bjorn.karlsson at readsoft.com, gregod at cs.rpi.edu, wekempf at cox.net