|
Boost : |
Subject: [boost] tiny lambda snippet that fails to compile with boost 1.46
From: Mark Van Dijk (Mark.VanDijk_at_[hidden])
Date: 2011-02-24 19:30:38
I have a question about a particular problem I'm having with boost::lambda. I've distilled it down to a tiny complete app (shown below).
The complier is complaining about bl::_1 is a const std::string, but &Map::value_type::second is a member_data_pointer to a non-const string. This line compiles with boost 1.42, but not in 1.46 (using MSVC 2008). I have two questions:
1) is the line of code in question actually valid? I.e. is this a boost::lambda bug or is this my bug?
2) If it is my bug, then to fix the code I need to coerce [&Map::value_type::second] to a CONST - problem is that the only way I can figure out is to use an ugly const_cast<>. Is there a cleaner way to do this?
Source code follows:
------------------------------------------------------------------------------------------------------------
#include <iostream>
#include <string>
#include <map>
#include <cassert>
#include <boost/assign.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>
namespace bl = boost::lambda;
int main()
{
// create two simple maps and populate them
typedef std::map<long, std::string> Map;
Map m = boost::assign::map_list_of(0, "hello ")(1, "world!"); // non-const map
Map const cm = boost::assign::map_list_of(0, "hello ")(1, "world!"); // const map
// this works:
// concatenate the std::string parts of the non-const map and send to std::cout
//
std::string output;
std::for_each(
m.begin(),
m.end(),
output += bl::bind(&Map::value_type::second, bl::_1));
std::cout << output << std::endl;
assert(output == "hello world!");
// works with boost 1.42, however it fails to compile with boost 1.46
// concatenate the std::string parts of the const map and send to std::cout
//
output.clear();
std::for_each(
cm.begin(),
cm.end(),
output += bl::bind(&Map::value_type::second, bl::_1)); // <---- COMPILER ERROR HERE WITH BOOST 1.46
std::cout << output << std::endl;
assert(output == "hello world!");
// this compiles, but uses an ugly const_cast<>
// concatenate the std::string parts of the const map and send to std::cout
//
output.clear();
std::for_each(
cm.begin(),
cm.end(),
output += bl::bind(const_cast<std::string const Map::value_type::*>(&Map::value_type::second), bl::_1)); // <---- UGLY
std::cout << output << std::endl;
assert(output == "hello world!");
return 0;
}
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk