[POSSIBLE BUG] boost::fusion::fold des not work as advertised

&)>' 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>'
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> 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

Marco Costalba wrote:
struct make_string {
template<typename T, typename State> struct result { typedef std::string type; };
Seems the docs have not all been updated, yet. This is the old result computation protocol. Today Fusion uses the std::result_of convention. In this case it's sufficient to replace the above code with typedef std::string result_type; For more complex result computation one can still use a nested 'result' metafunction, but it's always unary now and invoked with the signature: template< typename Signature > struct result; template< class Self, typename T0, typename T1 > struct result< Self(T0,T1) > { typedef /*...*/ type; }; Regards, Tobias

On 9/15/07, Tobias Schwinger <tschwinger@isonews2.com> wrote:
In this case it's sufficient to replace the above code with
typedef std::string result_type;
&)>' 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>'
Sorry but still does not compile: bash-3.1$ g++ -Iboost_dir -o test main.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> main2.cpp:27: instantiated from here boost_dir/boost/utility/result_of.hpp:68: error: wrong number of template arguments (1, should be 2) main2.cpp:12: 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:27: 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:27: 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$ The test now is: struct make_string { template<typename T, typename State> struct result { typedef std::string result_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; }

Marco Costalba wrote: <snip errors>
The test now is:
struct make_string { template<typename T, typename State> struct result { typedef std::string result_type; };
template<typename T> std::string operator()(const T& t, const std::string& str) const { return str + boost::lexical_cast<std::string>(t); } };
That's not what I meant. Don't just substitute the nested typedef but the whole metafunction: struct make_string { typedef std::string result_type; ... Regards, Tobias

Marco Costalba wrote:
On 9/15/07, Tobias Schwinger <tschwinger@isonews2.com> wrote:
That's not what I meant. Don't just substitute the nested typedef but the whole metafunction:
struct make_string { typedef std::string result_type;
For more info on this, see: http://boost.org/libs/utility/utility.htm#result_of and http://anubis.dkuug.dk/jtc1/sc22/wg21/docs/papers/2003/n1454.html Regards and thanks, Tobias! Cheers, -- Joel de Guzman http://www.boost-consulting.com http://spirit.sf.net
participants (3)
-
Joel de Guzman
-
Marco Costalba
-
Tobias Schwinger