Boost fusion problem
Hi guys, We're trying out the latest version of Boost (1.61, migrating from 1.55) and have some code calling the fusion library that now doesn't compile and it's not obvious (to me at least) why. I've created a simple program (below) to demonstrate the issue. As per the compile/run section below, this compiles and runs with Boost 1.55, not with 1.61. If anyone has any idea or pointers to what is wrong here I'd really appreciate it. Sorry if this isn't the right forum for this kind of issue too - if so please let me know how best to seek help on this. Regards Jess ******************** main.cpp #include <boost/fusion/algorithm/iteration/for_each.hpp> #include <boost/fusion/view/zip_view.hpp> #include <boost/fusion/tuple.hpp> #include <iostream> #include <string> struct Helper { template<typename Arg> void operator()(const Arg& arg) const { std::cout << boost::fusion::get<0>(arg) << std::endl; std::cout << boost::fusion::get<1>(arg) << std::endl; } }; int main() { const int myint(123); const double mydub(456.0); const std::string mystr("blah"); const bool mybool(false); typedef boost::fusion::tuple<const int&, const double&> Tuple1; typedef boost::fusion::tuple<const std::string&, const bool&> Tuple2; typedef boost::fusion::tuple<const Tuple1&, const Tuple2&> Tuple3; Helper helper; boost::fusion::for_each( boost::fusion::zip_view<Tuple3>( Tuple3(Tuple1(myint, mydub), Tuple2(mystr, mybool))), helper); return 0; } ******************** compile/run tests jess@flathead:~$ g++ --version g++ (Ubuntu 5.3.1-14ubuntu2) 5.3.1 20160413 Copyright (C) 2015 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. (boost 1.55) jess@flathead:~$ g++ -std=c++14 main.cpp jess@flathead:~$ ./a.out 123 blah 456 0 (boost 1.61) jess@flathead:~$ g++ -std=c++14 main.cpp In file included from /usr/local/include/boost/fusion/container/vector/vector10.hpp:25:0, from /usr/local/include/boost/fusion/view/transform_view/transform_view.hpp:22, from /usr/local/include/boost/fusion/algorithm/transformation/transform.hpp:11, from /usr/local/include/boost/fusion/view/zip_view/detail/begin_impl.hpp:14, from /usr/local/include/boost/fusion/view/zip_view/zip_view.hpp:16, from /usr/local/include/boost/fusion/view/zip_view.hpp:12, from main.cpp:2: /usr/local/include/boost/fusion/container/vector/vector.hpp: In instantiation of ‘constexpr boost::fusion::vector_detail::vector_data<std::integer_sequence<long unsigned int, _Idx ...>, T ...>::vector_data(boost::fusion::vector_detail::each_elem, U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; long unsigned int ...I = {0ul, 1ul}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’: /usr/local/include/boost/fusion/container/vector/vector.hpp:305:97: required from ‘boost::fusion::vector<T>::vector(U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’ /usr/local/include/boost/fusion/view/zip_view/zip_view.hpp:128:30: required from ‘constexpr boost::fusion::zip_view<Sequences>::zip_view(const Sequences&) [with Sequences = boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>]’ main.cpp:32:64: required from here /usr/local/include/boost/fusion/container/vector/vector.hpp:230:52: error: mismatched argument pack lengths while expanding ‘boost::fusion::vector_detail::store<I, T>’ : store<I, T>(std::forward<U>(var))... ^ /usr/local/include/boost/fusion/container/vector/vector.hpp: In instantiation of ‘constexpr boost::fusion::vector_detail::store<<anonymous>, T>::store() [with long unsigned int <anonymous> = 0ul; T = const boost::fusion::tuple<const int&, const double&>&]’: /usr/local/include/boost/fusion/container/vector/vector.hpp:230:52: required from ‘constexpr boost::fusion::vector_detail::vector_data<std::integer_sequence<long unsigned int, _Idx ...>, T ...>::vector_data(boost::fusion::vector_detail::each_elem, U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; long unsigned int ...I = {0ul, 1ul}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’ /usr/local/include/boost/fusion/container/vector/vector.hpp:305:97: required from ‘boost::fusion::vector<T>::vector(U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’ /usr/local/include/boost/fusion/view/zip_view/zip_view.hpp:128:30: required from ‘constexpr boost::fusion::zip_view<Sequences>::zip_view(const Sequences&) [with Sequences = boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>]’ main.cpp:32:64: required from here /usr/local/include/boost/fusion/container/vector/vector.hpp:137:24: error: value-initialization of reference type ‘const boost::fusion::tuple<const int&, const double&>&’ : elem() // value-initialized explicitly ^ /usr/local/include/boost/fusion/container/vector/vector.hpp: In instantiation of ‘constexpr boost::fusion::vector_detail::store<<anonymous>, T>::store() [with long unsigned int <anonymous> = 1ul; T = const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&]’: /usr/local/include/boost/fusion/container/vector/vector.hpp:230:52: required from ‘constexpr boost::fusion::vector_detail::vector_data<std::integer_sequence<long unsigned int, _Idx ...>, T ...>::vector_data(boost::fusion::vector_detail::each_elem, U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; long unsigned int ...I = {0ul, 1ul}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’ /usr/local/include/boost/fusion/container/vector/vector.hpp:305:97: required from ‘boost::fusion::vector<T>::vector(U&& ...) [with U = {const boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>&}; T = {const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&}]’ /usr/local/include/boost/fusion/view/zip_view/zip_view.hpp:128:30: required from ‘constexpr boost::fusion::zip_view<Sequences>::zip_view(const Sequences&) [with Sequences = boost::fusion::tuple<const boost::fusion::tuple<const int&, const double&>&, const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&>]’ main.cpp:32:64: required from here /usr/local/include/boost/fusion/container/vector/vector.hpp:137:24: error: value-initialization of reference type ‘const boost::fusion::tuple<const std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >&, const bool&>&’
On Tue, 24 May 2016 19:09:02 +1000 Jess Morecroft <jess@aecapital.com.au> wrote:
Hi guys,
We're trying out the latest version of Boost (1.61, migrating from 1.55) and have some code calling the fusion library that now doesn't compile and it's not obvious (to me at least) why. I've created a simple program (below) to demonstrate the issue. As per the compile/run section below, this compiles and runs with Boost 1.55, not with 1.61.
If anyone has any idea or pointers to what is wrong here I'd really appreciate it. Sorry if this isn't the right forum for this kind of issue too - if so please let me know how best to seek help on this.
Regards Jess
This is a regression caused by the upgrades for C++11. Compiling in C++03 mode still works with Boost 1.61. The problem is the nested sequence, the new C++11 version is trying to unpack the inner sequence for a conversion move when it should be moving the entire inner sequence. The problem is caused by the [incorrect dispatch method][0] being selected. Little late for me to attempt a fix, but I should be able to do a bit later this week if no one else can. Lee [0]https://github.com/boostorg/fusion/blob/master/include/boost/fusion/containe...
Hi Lee, We actually noticed that by changing the tuple to a (fusion) vector, it just works. This was unexpected as we'd thought/read in the boost doc that tuple was just effectively an alias for a vector, but apparently not. This is good enough for us so no solution required beyond this. Regards Jess On 25 May 2016 at 15:13, Lee Clagett <forum@leeclagett.com> wrote:
On Tue, 24 May 2016 19:09:02 +1000 Jess Morecroft <jess@aecapital.com.au> wrote:
Hi guys,
We're trying out the latest version of Boost (1.61, migrating from 1.55) and have some code calling the fusion library that now doesn't compile and it's not obvious (to me at least) why. I've created a simple program (below) to demonstrate the issue. As per the compile/run section below, this compiles and runs with Boost 1.55, not with 1.61.
If anyone has any idea or pointers to what is wrong here I'd really appreciate it. Sorry if this isn't the right forum for this kind of issue too - if so please let me know how best to seek help on this.
Regards Jess
This is a regression caused by the upgrades for C++11. Compiling in C++03 mode still works with Boost 1.61. The problem is the nested sequence, the new C++11 version is trying to unpack the inner sequence for a conversion move when it should be moving the entire inner sequence. The problem is caused by the [incorrect dispatch method][0] being selected. Little late for me to attempt a fix, but I should be able to do a bit later this week if no one else can.
Lee
[0] https://github.com/boostorg/fusion/blob/master/include/boost/fusion/containe... _______________________________________________ Boost-users mailing list Boost-users@lists.boost.org http://lists.boost.org/mailman/listinfo.cgi/boost-users
-- -- AE CAPITAL Suite 1, 2A River St, South Yarra, Melbourne, VIC 3141 Australia p +61 3 9020 7802 m +61 (0)401 254 350 AE Capital Pty Limited (ACN 153 242 865) is regulated by the Australian Securities & Investments Commission and is a Corporate Authorised Representative of JFM Pty Limited (ACN 125 150 656), holder of an Australian Financial Services Licence (AFSL 314585).
On Mon, 30 May 2016 11:52:09 +1000 Jess Morecroft <jess@aecapital.com.au> wrote:
Hi Lee,
We actually noticed that by changing the tuple to a (fusion) vector, it just works. This was unexpected as we'd thought/read in the boost doc that tuple was just effectively an alias for a vector, but apparently not. This is good enough for us so no solution required beyond this.
Regards Jess
Yes I noticed this as well during my testing for a patch. In C++03 and C++11 `fusion::tuple` inherits from `fusion::vector`, so they are functionally identical but unique types. So copying/moving from tuple to vector (or vice-versa) triggers the "copy from another sequence type" code. You found a bug in that code for C++11, and while trying to identify a fix I found a similar bug in the C++03 version, and issues with the C++11 list too. Joel has [merged my fix][0] for your particular use case, and I hope to continue working on a fixes for the other cases too. Lee [0] https://github.com/boostorg/fusion/pull/132
participants (2)
-
Jess Morecroft
-
Lee Clagett