Opened 5 years ago

Last modified 5 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:


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 Changed 5 years ago by Eric Niebler

I should note that it actually does compile with msvc, but that's a compiler bug. With gcc and clang, it fails.

comment:2 Changed 5 years ago by anonymous

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:3 Changed 5 years ago by Joel de Guzman

woops, that anonymous is Joel.

comment:4 Changed 5 years ago by Eric Niebler

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:5 Changed 5 years ago by Eric Niebler

Oh, you're right about fold. It works on gcc, but fails on clang 3.3.

comment:6 Changed 5 years ago by Joel de Guzman

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.

Note: See TracTickets for help on using tickets.