Opened 12 years ago
Closed 8 years ago
#5408 closed Bugs (wontfix)
fold(transform(.... )) gives erroneous result: dangling reference?
Reported by: | Owned by: | Joel de Guzman | |
---|---|---|---|
Milestone: | To Be Determined | Component: | fusion |
Version: | Boost 1.47.0 | Severity: | Problem |
Keywords: | Cc: | joel@… |
Description
The code below demonstrates a problem using fusion's transform on a fold view in conjunction with a phoenix functional. It produces the output:
Should be the same: 1 =? 4.59177e-41
it should produce
Should be the same: 1 =? 1
Thanks, Joe
#include <iostream> #include <cmath> #include <boost/detail/lightweight_test.hpp> #include <boost/spirit/include/phoenix_core.hpp> #include <boost/spirit/include/phoenix_operator.hpp> #include <boost/spirit/include/phoenix_function.hpp> #include <boost/fusion/container.hpp> #include <boost/fusion/functional.hpp> #include <boost/fusion/include/io.hpp> #include <boost/fusion/include/fold.hpp> #include <boost/fusion/include/transform.hpp> #include <boost/type_traits.hpp> #include <boost/mpl/assert.hpp> using namespace boost::fusion; using namespace boost::phoenix; typedef float OutputType; // A general error function, measuring the difference between two output patterns. struct error_function3 { template <typename Outputs1, typename Outputs2> struct result { typedef OutputType type; }; template <typename Outputs1, typename Outputs2> OutputType operator()(Outputs1& outputs1, Outputs2& outputs2) const { using boost::phoenix::arg_names::_1; using boost::phoenix::arg_names::_2; using boost::fusion::fold; using boost::fusion::transform; float bad_result = fold(transform(outputs1, outputs2, (_1 - _2) * (_1 - _2)), 0, _1 + _2); float good_result = fold(as_vector(transform(outputs1, outputs2, (_1 - _2) * (_1 - _2))), 0, _1 + _2); std::cout << "Should be the same: " << good_result << " =? " << bad_result << std::endl; return good_result; } }; int main() { using boost::phoenix::arg_names::_1; using boost::phoenix::arg_names::_2; vector<OutputType, OutputType> o1 = make_vector(1., 2.); vector<OutputType, OutputType> o2 = make_vector(2., 3.); boost::phoenix::function<error_function3> const error; std::cout << error(_1, _2)(o1, o2) << std::endl; }
Change History (5)
comment:1 by , 12 years ago
Summary: | transform(fold(.... )) gives erroneous result: dangling reference? → fold(transform(.... )) gives erroneous result: dangling reference? |
---|
comment:2 by , 12 years ago
Cc: | added |
---|
comment:3 by , 12 years ago
Yes, that's fine! :) Now that I understand the changes to result_of I'm happy with moving to Pheonix 3.
comment:5 by , 8 years ago
Resolution: | → wontfix |
---|---|
Status: | new → closed |
Note:
See TracTickets
for help on using tickets.
I suggest you use Phoenix-3 instead. It is in the Boost trunk. The problem here is that Phoenix-2 has a old and flaky result-type deduction scheme. Phoenix-3 is better. The changes required are minimal. First use the proper includes:
Then, change the result-of of error_function3:
With the changes, I am getting: