Opened 9 years ago
Last modified 9 years ago
#8775 new Bugs
fusion transform and fold not respecting const-ness of the sequence
Reported by: | Eric Niebler | Owned by: | Joel de Guzman |
---|---|---|---|
Milestone: | To Be Determined | Component: | fusion |
Version: | Boost Development Trunk | Severity: | Problem |
Keywords: | Cc: |
Description
The following does not compile:
#include <boost/fusion/include/vector.hpp> #include <boost/fusion/include/transform.hpp> #include <boost/fusion/include/fold.hpp> #include <boost/fusion/include/copy.hpp> namespace fusion = boost::fusion; struct F { typedef int result_type; int operator()(int state, int & val) const { return state; } }; struct G { typedef int result_type; int operator()(int & val) const { return val; } }; int main() { fusion::vector<int, int> v(1,2); fusion::vector<int, int> v2; // fold does not respect constness fusion::fold(v, 42, F()); // transform does not respect constness fusion::copy(fusion::transform(v, G()), v2); }
In my opinion, it should.
Change History (6)
comment:1 by , 9 years ago
comment:2 by , 9 years ago
I'm not sure I understand. Both sequences are non-const above. Also, the call to fold compiles on gcc 4.7.2. Should it not? I'll take a look at the second as soon as I understand some more. What am I missing?
comment:4 by , 9 years ago
Right, the sequences are both non-const lvalues, so the elements passed to F
and G
should also be non-const lvalues. But they're not. They're const lvalues, which means they can't bind to the non-const references.
You should double-check that gcc compiles it successfully. I just tested locally with gcc 4.7.0 and gcc 4.8.1, and compilation fails for both, as well as for clang-trunk.
A quick inspection of the code shows why the transform
call fails to compile. There is no overload of transform
that takes a non-const sequence. fold
is tricker. You would need to dig to find out what's going on there.
comment:6 by , 9 years ago
Originally, Fusion algorithms are pure FP style const non mutating. Why? because they are held by reference and when you concat/build compound algos, my thinking was that it would be weird to have some of the algos mutate the sequence. Slowly, non const versions crept in. People kept on asking. I guess it's time to break free from the design and have all fusion algos take const and non-const sequences.
I should note that it actually does compile with msvc, but that's a compiler bug. With gcc and clang, it fails.