Modify

Opened 5 years ago

Closed 5 years ago

#6915 closed Bugs (fixed)

boost::fusion::result_of::invoke compilation errors

Reported by: ulidtko@… Owned by: djowel
Milestone: To Be Determined Component: fusion
Version: Boost 1.49.0 Severity: Problem
Keywords: Cc:

Description

In Boost.Fusion 1.49.0, boost::fusion::result_of::invoke metafunction causes compilation errors in some cases of SFINAE usage.

See attachments for reproducing example.

Please note how the code works with trivial metafunction (subst_failure_if_not_int), and does not with boost::fusion::result_of::invoke, while being used in identical manner.

Also note that the following line:

  try_invoke<F, boost::fusion::vector<float>> (0);

may compile or not depending on the BOOST_RESULT_OF_USE_DECLTYPE switch under GCC. Which is a fair clue of that this is probably boost's bug.

Compiler error messages

MSVC 9

d:\boost\1_49_0\boost\fusion\functional\invocation\invoke.hpp(199) : error C2039: 'type' : is not a member of 'boost::result_of<F>'
d:\boost\1_49_0\boost\fusion\functional\invocation\invoke.hpp(159) : see reference to class template instantiation 'boost::fusion::detail::invoke_impl<Function,Sequence>' being compiled
..\substitution_failure_test.cpp(60) : see reference to class template instantiation 'boost::fusion::result_of::invoke<Function,Sequence>' being compiled
        with
        [
            Function=F,
            Sequence=boost::fusion::vector<float>
        ]

GCC 4.5.3

When compiling with #define BOOST_RESULT_OF_USE_DECLTYPE 1:

In file included from D:/boost/1_49_0/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:0,
                 from D:/boost/1_49_0/boost/utility/result_of.hpp:95,
                 from D:/boost/1_49_0/boost/fusion/support/detail/segmented_fold_until_impl.hpp:13,
                 from D:/boost/1_49_0/boost/fusion/sequence/intrinsic/detail/segmented_begin_impl.hpp:15,
                 from D:/boost/1_49_0/boost/fusion/sequence/intrinsic/detail/segmented_begin.hpp:10,
                 from D:/boost/1_49_0/boost/fusion/sequence/intrinsic/begin.hpp:17,
                 from D:/boost/1_49_0/boost/fusion/container/vector/vector10.hpp:15,
                 from D:/boost/1_49_0/boost/fusion/container/vector.hpp:12,
                 from D:/boost/1_49_0/boost/fusion/container.hpp:10,
                 from substitution_failure_test.cpp:5:
D:/boost/1_49_0/boost/utility/detail/result_of_iterate.hpp: In instantiation of ‘boost::detail::cpp0x_result_of_impl<F(junk&)>’:
D:/boost/1_49_0/boost/utility/detail/result_of_iterate.hpp:52:1:   instantiated from ‘boost::result_of<F(junk&)>’
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:199:60:   instantiated from ‘boost::fusion::detail::invoke_impl<F, boost::fusion::vector<junk>, 1, false, true>’
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:159:30:   instantiated from ‘boost::fusion::result_of::invoke<F, boost::fusion::vector<junk> >’
substitution_failure_test.cpp:65:47:   instantiated from here
D:/boost/1_49_0/boost/utility/detail/result_of_iterate.hpp:64:5: error: no match for call to ‘(F) (junk&)’
substitution_failure_test.cpp:39:6: note: candidate is: int F::operator()(float)

Without:

In file included from D:/boost/1_49_0/boost/preprocessor/iteration/detail/iter/forward1.hpp:52:0,
                 from D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:93,
                 from D:/boost/1_49_0/boost/fusion/functional/invocation.hpp:12,
                 from D:/boost/1_49_0/boost/fusion/functional.hpp:12,
                 from substitution_failure_test.cpp:7:
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp: In instantiation of ‘boost::fusion::detail::invoke_impl<F, boost::fusion::vector<float>, 1, false, true>’:
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:159:30:   instantiated from ‘boost::fusion::result_of::invoke<F, boost::fusion::vector<float> >’
substitution_failure_test.cpp:62:48:   instantiated from here
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:199:60: error: no type named ‘type’ in ‘struct boost::result_of<F(float&)>’
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp: In instantiation of ‘boost::fusion::detail::invoke_impl<F, boost::fusion::vector<junk>, 1, false, true>’:
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:159:30:   instantiated from ‘boost::fusion::result_of::invoke<F, boost::fusion::vector<junk> >’
substitution_failure_test.cpp:65:47:   instantiated from here
D:/boost/1_49_0/boost/fusion/functional/invocation/invoke.hpp:199:60: error: no type named ‘type’ in ‘struct boost::result_of<F(junk&)>’

PS: I ♥ search engines.

Attachments (1)

substitution_failure_test.cpp (1.8 KB) - added by ulidtko@… 5 years ago.
reproducing example

Download all attachments as: .zip

Change History (4)

Changed 5 years ago by ulidtko@…

reproducing example

comment:1 Changed 5 years ago by viboes

  • Component changed from None to fusion
  • Owner set to djowel

comment:2 Changed 5 years ago by anonymous

First reported here: http://stackoverflow.com/questions/10632848/boost-fusion-invoke-and-sfinae

If fixed, closure in the form of a note on the original Stack Overflow question would be very much appreciated.

comment:3 Changed 5 years ago by djowel

  • Resolution set to fixed
  • Status changed from new to closed

I fixed this in trunk. The first test:

try_invoke<F, boost::fusion::vector<float>> (0);

now compiles just fine. The second test however is (IMO) erroneous:

try_invoke<F, boost::fusion::vector<junk>> (0);

This cannot select the fallback overload because

typename boost::fusion::result_of::invoke<F, Sequence>::type

will be erroneous and will not trigger SFINAE. The code attached is equivalent to this:

#include <boost/utility/result_of.hpp> #include <iostream>

int foo(int); struct junk {};

template <typename F, typename Arg> typename boost::result_of<F(Arg)>::type call(int) {

return F(Arg());

}

template <typename F, typename Arg> void call(long) {

fallback std::cout << "fallback" << std::endl;

}

int main() {

call<int(*)(int), junk>(123);

}

which will give you an error. Notice though that if I replace:

typename boost::result_of<F(Arg)>::type

with

decltype(F(Arg()))

then it works. So the question now falls into the hands of the Boost::result_of maintainers. If you think this should work, then, go add a ticket to boost::result_of.

I'm closing this one.

Add Comment

Modify Ticket

Change Properties
Set your email in Preferences
Action
as closed The owner will remain djowel.
The resolution will be deleted. Next status will be 'reopened'.
Author


E-mail address and user name can be saved in the Preferences.

 
Note: See TracTickets for help on using tickets.