Opened 10 years ago
Closed 10 years ago
#6915 closed Bugs (fixed)
boost::fusion::result_of::invoke compilation errors
Reported by: | Owned by: | Joel de Guzman | |
---|---|---|---|
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)
Change History (4)
by , 10 years ago
Attachment: | substitution_failure_test.cpp added |
---|
comment:1 by , 10 years ago
Component: | None → fusion |
---|---|
Owner: | set to |
comment:2 by , 10 years ago
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 by , 10 years ago
Resolution: | → fixed |
---|---|
Status: | new → 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.
reproducing example