#10676 closed Bugs (fixed)
[fusion] Compile errors with boost::fusion::fold due to boost::result_of picking wrong overload
Reported by: | 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)
Change History (12)
comment:1 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | new → closed |
comment:2 by , 8 years ago
Resolution: | fixed |
---|---|
Status: | closed → reopened |
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 , 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 , 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 , 8 years ago
Yes please. I can't repro your problem from the test case above. All fusion tests pass as well.
comment:6 by , 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:8 by , 8 years ago
Resolution: | → fixed |
---|---|
Status: | reopened → closed |
comment:9 by , 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 , 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.
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.