4

I try to transform all elements of a vector v into their log values with some other arithmetic operations (not in the code). How can I use Boost.Lambda to achieve that?

As I say, there are some more arithmetic operations, so an expression with Boost.Bind doesn't work for me (too complicated, too long, unreadable).

I don't want to use C++11 lambdas as well. But... would it change anything?

My code is like:

#include <boost/lambda/lambda.hpp> #include <cmath> #include <vector> void testLambda() { using namespace boost::lambda; std::vector<double> v; v.push_back(1); v.push_back(2); v.push_back(3); std::transform(v.begin(), v.end(), v.begin(), _1 / 0.5); // works std::transform(v.begin(), v.end(), v.begin(), log(_1) / 0.5); // produces error //std::transform(v.begin(), v.end(), v.begin(), std::log(_1) / 0.5); // produces error //std::transform(v.begin(), v.end(), v.begin(), static_cast<double(*)(double)>(std::log)(_1) / 0.5); // produces error } 

When I try to compile the code, MSVC2010 gives the error:

Error 1 error C2665: 'log' : none of the 3 overloads could convert all the argument types C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h(120): could be 'double log(double)' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h(527): or 'float log(float)' C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\math.h(575): or 'long double log(long double)' while trying to match the argument list '(boost::lambda::placeholder1_type)' 

Update 1: I don't want to write functors for it, think that I would have to have a dozen of them, what then?

Update 2: I am able to do it with C++11 lambdas, but it's not what I ask for:

 std::transform(v.begin(), v.end(), v.begin(), [](const double & x) { return log(x) / 0.5; }); 
5
  • stackoverflow.com/a/1931602/98654 has an example of using multiple lambda/binds together -- is that what you are looking for? Commented Jul 18, 2013 at 14:30
  • 1
    just write a plain old function object Commented Jul 18, 2013 at 14:33
  • @NateKohl I cannot get it work together lambdas and bind. Can you give a solution, please? Commented Jul 18, 2013 at 14:46
  • It might help if you provide an example of the actual transformations that you'd like to perform. (Just needing to do log is a good case for std::bind or boost::bind.) Commented Jul 18, 2013 at 14:53
  • Things that could solve your problem that you ruled out: explicit loops, writing a function that does what you want, bind, [](){} lambdas, writing a functor, std::function, auto... Did I miss anything? Commented Jul 18, 2013 at 15:16

1 Answer 1

2

How about a proper C++11 lamba? MSVC2010 has limited support, but plain math should work fine.

std::transform(v.begin(), v.end(), v.begin(), [](const double& x) { return log(x); }); 

Or an old-school solution to the problem:

struct f { double operator()(const double& x) { return log(x); } } std::transform(v.begin(), v.end(), v.begin(), f); 

Anyways, I see no need for fancy lambda stuff in the code you posted since you seem to be modifying the vector's elements in-place:

std::vector<double> v; v.push_back(1); v.push_back(2); v.push_back(3); for(const std::vector<double>::iterator it = v.begin(); it != v.end(); ++it) { /* fancy math stuff here */ *it = log(*it); } 

This is IMHO the cleanest way to do this. My final C++ solution (by far the most expressive and simplest of every alternative) would be:

for(auto&& x : v) { /* fancy math stuff here */ x = log(x); } 
Sign up to request clarification or add additional context in comments.

3 Comments

I don't want C++11 lambdas, nor functors. The former -- C++03 constrained. The latter -- unreadable if there are lots of them.
@Curdeius I'd guess you're out of luck; Boost.Lambda's documentation has an example int foo(int); for_each(v.begin(), v.end(), _1 = bind(foo, _1)); which does wat you want, but uses bind. C++03 is just not a functional language. What prevents you from just using a for loop?
Nothing prevents me from doing a for loop, I just wanted to be consistent with the rest of my code.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.