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: