Opened 12 years ago

Closed 12 years ago

#4967 closed Patches (fixed)

apply_visitor_delayed_t 's operator() is not const correct

Reported by: zhuo.qiang@… Owned by: ebf
Milestone: To Be Determined Component: variant
Version: Boost 1.45.0 Severity: Problem
Keywords: Cc: prabhu.swain@…

Description

The operator() overload in Boost.Variant's boost::apply_visitor_delayed_t is not const qualified which I think could be safely add.

The benefit of adding const is as following:

There are some generic function need to store and call the apply_visitor_delayed_t instance, transform_iterator & transform_range, for example. The following code will not compile without the const quality:


using namespace boost; using namespace std;

typedef variant<int, string> V;

struct times_2_t : public static_visitor<int> {

template<class T> int operator()(T const& t) const {

return 2 * t;

};

int operator()(string const& s) const {

return 2 * s.size();

};

};

BOOST_AUTO_TEST_CASE(Test) {

vector<V> all; all.push_back(1); all.push_back(2);

times_2_t times_2; int const result = boost::accumulate(

all | boost::adaptors::transformed(apply_visitor(times_2)), 0);

BOOST_CHECK_EQUAL(6, result);

}


One way to fix this is using a boost::funciton to hold the apply_visitor_delayed_t instance and pass the wrapper to transformed:


times_2_t times_2; function<int(V const&)> f = apply_visitor(times_2); int const result = boost::accumulate(

all | boost::adaptors::transformed(apply_visitor(f)), 0);


However, this will make simple things complex and have runtime cost.

So a more direct fix would be add the harmless const qualify to the operator() for apply_visitor_delayed_t

The attached is a simply patch:

Attachments (1)

patch.diff (867 bytes ) - added by anonymous 12 years ago.
The patch for adding the harmless const qualify for the apply_visitor_delayed_t

Download all attachments as: .zip

Change History (6)

by anonymous, 12 years ago

Attachment: patch.diff added

The patch for adding the harmless const qualify for the apply_visitor_delayed_t

comment:1 by anonymous, 12 years ago

The second code snipper should be this:

    
times_2_t times_2; 
function<int(V const&)> f = apply_visitor(times_2); 
int const result = boost::accumulate(
        all | boost::adaptors::transformed(f), 0);

comment:2 by Steven Watanabe, 12 years ago

Simply making the overloads const is not harmless, because it will break code that uses function objects that aren't const. The right way is to add const overloads.

comment:3 by Steven Watanabe, 12 years ago

Never mind. I'm obviously not looking at the code carefully enough.

comment:4 by prabhu.swain@…, 12 years ago

Cc: prabhu.swain@… added

comment:5 by Steven Watanabe, 12 years ago

Resolution: fixed
Status: newclosed

(In [67605]) Make operator() const. Fixes #4967

Note: See TracTickets for help on using tickets.