Opened 8 years ago

Closed 8 years ago

Last modified 8 years ago

#10676 closed Bugs (fixed)

[fusion] Compile errors with boost::fusion::fold due to boost::result_of picking wrong overload

Reported by: Jared Grubb <jaredgrubb@…> Owned by: Joel de Guzman
Milestone: To Be Determined Component: fusion
Version: Boost 1.56.0 Severity: Regression
Keywords: Cc:

Description

I was updating from boost-1.51 to boost-1.56 and some of a parsing library I have now fails to compile.

Notice how the errors occur in overloads requiring "const long&" but the Visitor takes mutable values (long&). Somehow, it picks const and then digs down.

I have two workarounds:

  • use BOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK
  • add an explicit instantiation of boost::fusion::result_of to disable the selection that is causing the problem.
#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/algorithm/iteration/fold.hpp>

#if WORKAROUND
struct Visitor;
namespace boost { namespace fusion { namespace result_of {
     template<typename Seq>
     struct fold<Seq const, int const, Visitor> {
        /* Missing 'type' to disable this selection earlier */
    };
} } }
#endif

struct Visitor
{
    using result_type = int;

    int operator()(int sum, long&)
    {
        return sum;
    }
};

int main()
{
    boost::fusion::vector<long> vec;

    Visitor visitor{};
    boost::fusion::fold(vec, 0, visitor);
}

Error:

$ clang++ --version
Apple LLVM version 6.0 (clang-600.0.39) (based on LLVM 3.5svn)
Target: x86_64-apple-darwin14.0.0
Thread model: posix

[ Using boost-1.51 ]
$ clang++ x.cpp --std=c++11 -DWORKAROUND
$ clang++ x.cpp --std=c++11

[ Using boost-1.56 ]
$ clang++ x.cpp --std=c++11 -DWORKAROUND

$ clang++ x.cpp --std=c++11 -DBOOST_RESULT_OF_USE_TR1_WITH_DECLTYPE_FALLBACK

$ clang++ x.cpp --std=c++11
In file included from x.cpp:2:
In file included from /Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/fold.hpp:33:
/Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/detail/preprocessed/fold.hpp:265:24: error: no type named 'type' in
      'boost::result_of<Visitor (const int &, const long &)>'
                    >::type
                    ~~~^~~~
/Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/detail/preprocessed/fold.hpp:278:17: note: in instantiation of template
      class 'boost::fusion::detail::result_of_first_unrolledfold<const int &, boost::fusion::vector_iterator<const boost::fusion::vector<long,
      boost::fusion::void_, 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>, Visitor, 1>' requested here
                result_of_first_unrolledfold<
                ^
/Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/detail/preprocessed/fold.hpp:314:13: note: in instantiation of template
      class 'boost::fusion::detail::fold_impl<1, const int &, const boost::fusion::vector<long, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_>, Visitor>' requested here
          : fold_impl<
            ^
/Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/detail/preprocessed/fold.hpp:328:13: note: in instantiation of template
      class 'boost::fusion::detail::result_of_fold<const boost::fusion::vector<long, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_>, const int, Visitor, false>' requested here
          : detail::result_of_fold<
            ^
/Users/grubber/Downloads/boost_1_56_0/boost/fusion/algorithm/iteration/detail/preprocessed/fold.hpp:352:32: note: in instantiation of template
      class 'boost::fusion::result_of::fold<const boost::fusion::vector<long, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, const
      int, Visitor>' requested here
    inline typename result_of::fold<
                               ^
x.cpp:29:5: note: while substituting deduced template arguments into function template 'fold' [with Seq = boost::fusion::vector<long,
      boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_,
      boost::fusion::void_, boost::fusion::void_, boost::fusion::void_>, State = int, F = Visitor]
    boost::fusion::fold(vec, 0, visitor);
    ^
1 error generated.

Attachments (2)

fusion_error.txt (41.5 KB ) - added by Jürgen Hunold 8 years ago.
full error messages
fold.cpp (510 bytes ) - added by Jürgen Hunold 8 years ago.
Test case

Download all attachments as: .zip

Change History (12)

comment:1 by Joel de Guzman, 8 years ago

Resolution: fixed
Status: newclosed

Fixed in develop branch. for now, we'll use tr1_result_of. we'll have to do an overhaul of the fold implementation because making it sfinae friendly goes deep down into the low level internals.

by Jürgen Hunold, 8 years ago

Attachment: fusion_error.txt added

full error messages

comment:2 by Jürgen Hunold, 8 years ago

Resolution: fixed
Status: closedreopened

This breaks code here.

In file included from BOOST_ROOT/boost/fusion/support/detail/segmented_fold_until_impl.hpp:14: BOOST_ROOT/boost/utility/result_of.hpp:189:46: error: 'result' following the 'template' keyword does not refer to a template struct result_of_nested_result : F::template result<FArgs>

Full message attached file "fusion_error.txt".

comment:3 by Joel de Guzman, 8 years ago

Are you using the test case above? I can't reproduce the error you are getting. Did you pull boost from develop branch?

comment:4 by anonymous, 8 years ago

I'm using Boost.Trunk from develop branch of course, as the commit is not yet merged to master. Our own code breaks. Please drop me a note if you need a test case. Though it might take some days to extract it.

comment:5 by Joel de Guzman, 8 years ago

Yes please. I can't repro your problem from the test case above. All fusion tests pass as well.

by Jürgen Hunold, 8 years ago

Attachment: fold.cpp added

Test case

comment:6 by Jürgen Hunold, 8 years ago

Attached test file "fold.cpp". Fails to compile with:

  • Ubuntu clang version 3.5-1ubuntu1 (trunk) (based on LLVM 3.5)
  • gcc version 4.9.1 (Ubuntu 4.9.1-3ubuntu2~14.04.1)
  • clang trunk

on fusion develop. master branch works fine.

comment:7 by anonymous, 8 years ago

Ok, gotya. New fix pushed to develop. Please check.

comment:8 by Joel de Guzman, 8 years ago

Resolution: fixed
Status: reopenedclosed

comment:9 by Jürgen Hunold, 8 years ago

Thanks for the quick fix. The original code works again. Does it make sense to add the test case to the Fusion test suite? The planned massive overhaul would worry me otherwise.

comment:10 by Joel de Guzman, 8 years ago

Yes, I plan to do just that. Don't worry about the overhaul. It will be limited to fold only. I think it's best to do incremental evolution for C++14 instead of fighting with the old code.

Note: See TracTickets for help on using tickets.