From: Marco Costalba (mcostalba_at_[hidden])
Date: 2007-09-15 04:16:33


fusion::fold des not work as advertised.

When I try to compile the example shown in the fold fusion documentation:

#include <boost/fusion/sequence/container/vector.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>
#include <boost/static_assert.hpp>
#include <boost/lexical_cast.hpp>
#include <boost/assert.hpp>

using namespace boost::fusion;

struct make_string
{
    template<typename T, typename State>
    struct result
    {
        typedef std::string type;
    };

    template<typename T>
    std::string operator()(const T& t, const std::string& str) const
    {
        return str + boost::lexical_cast<std::string>(t);
    }
};

int main(int argc, char* argv[]) {
        const vector<int,int> vec(1,2);
        assert(fold(vec,std::string(""), make_string()) == "12");
        return 0;
}

I get this...

bash-3.1$ g++ -Iboost_dir -o test main2.cpp

boost_dir/boost/utility/result_of.hpp: In instantiation of
'boost::detail::result_of_nested_result<make_string, make_string
()(const int&, const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&)>':
boost_dir/boost/utility/result_of.hpp:34: instantiated from
'boost::detail::result_of_impl<make_string, make_string ()(const int&,
const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&), false>'
boost_dir/boost/utility/result_of.hpp:27: instantiated from
'boost::result_of<make_string ()(const int&, const
std::basic_string<char, std::char_traits<char>, std::allocator<char>
>&)>'
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:41:
instantiated from
'boost::fusion::detail::fold_apply<boost::fusion::vector_iterator<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, 0>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string>'
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:202:
instantiated from
'boost::fusion::detail::result_of_unrolled_fold<boost::fusion::vector_iterator<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, 0>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string, 2>'
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:227:
instantiated from 'boost::fusion::detail::choose_fold<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, make_string, true>'
boost_dir/boost/fusion/algorithm/iteration/fold.hpp:29: instantiated
from 'boost::fusion::result_of::fold<const boost::fusion::vector<int,
int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string>'
main2.cpp:43: instantiated from here
boost_dir/boost/utility/result_of.hpp:68: error: wrong number of
template arguments (1, should be 2)
main2.cpp:27: error: provided for 'template<class T, class State>
struct make_string::result'
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp: In
instantiation of
'boost::fusion::detail::fold_apply<boost::fusion::vector_iterator<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, 0>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string>':
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:202:
instantiated from
'boost::fusion::detail::result_of_unrolled_fold<boost::fusion::vector_iterator<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, 0>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string, 2>'
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:227:
instantiated from 'boost::fusion::detail::choose_fold<const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>, std::basic_string<char, std::char_traits<char>,
std::allocator<char> >, make_string, true>'
boost_dir/boost/fusion/algorithm/iteration/fold.hpp:29: instantiated
from 'boost::fusion::result_of::fold<const boost::fusion::vector<int,
int, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_>, std::basic_string<char,
std::char_traits<char>, std::allocator<char> >, make_string>'
main2.cpp:43: instantiated from here
boost_dir/boost/fusion/algorithm/iteration/detail/fold.hpp:41: error:
no type named 'type' in 'struct boost::result_of<make_string ()(const
int&, const std::basic_string<char, std::char_traits<char>,
std::allocator<char> >&)>'
main2.cpp: In function 'int main(int, char**)':
main2.cpp:43: error: no matching function for call to 'fold(const
boost::fusion::vector<int, int, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
boost::fusion::void_>&, std::string, make_string)'
bash-3.1$

My environment is:

bash-3.1$ g++ -v
Using built-in specs.
Target: i586-mandriva-linux-gnu
Configured with: ../configure --prefix=/usr --libexecdir=/usr/lib
--with-slibdir=/lib --mandir=/usr/share/man --infodir=/usr/share/info
--enable-checking=release
--enable-languages=c,c++,ada,fortran,objc,obj-c++,java
--host=i586-mandriva-linux-gnu --with-cpu=generic --with-system-zlib
--enable-threads=posix --enable-shared --enable-long-long
--enable-__cxa_atexit --disable-libunwind-exceptions
--enable-clocale=gnu --enable-java-awt=gtk
--with-java-home=/usr/lib/jvm/java-1.4.2-gcj-1.4.2.0/jre
--enable-gtk-cairo --disable-libjava-multilib --enable-ssp
--disable-libssp
Thread model: posix
gcc version 4.2.1 20070704 (prerelease) (4.2.1-3mdv2008.0)

boost::fusion has been downloaded from trunk this week.

Thanks for any help on how to use fold(), currently I'm stopped on
fold() semantics in my project.

Marco