3

On the following code, how can i rewrite the for loop by using a std::for_each instruction. I tried to use boost::lambda::_1, boost::bind, but I could not make it working.

#include <vector>
#include <iostream>
#include <cstring>
#include <cstdlib>

int main() 
{ 
  std::vector<int(*)(const char*)> processors; 
  processors.push_back(std::atoi); 
  processors.push_back(reinterpret_cast<int(*)(const char*)>(std::strlen)); 

  const char data[] = "1.23"; 

  for(std::vector<int(*)(const char*)>::iterator it = processors.begin();
      it != processors.end(); ++it) 
    std::cout << (*it)(data) << std::endl;
}

Any hint to help me solve this problem are welcome.

EDIT: Solution

#include <vector>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <boost/function.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/lambda/bind.hpp>

int main() 
{ 
  std::vector<boost::function<int(const char*)> > processors; 
  processors.push_back(std::atoi); 
  processors.push_back(std::strlen); 

  const char data[] = "1.23"; 

  namespace bl = boost::lambda;
  std::for_each(processors.begin(), processors.end(),
      std::cout << bl::bind(bl::_1, data) << "\n");
}
8
  • 4
    Note that casting between function-pointer types and then dereferencing them is undefined. Commented Apr 30, 2011 at 0:50
  • What went wrong when you used std::for_each? What did you pass to for_each as the third parameter... i.e. the thing to do for each element of the range? Commented Apr 30, 2011 at 0:53
  • 1
    Since you're already using Boost's functional implementation, you should be able to use boost::function<int(const char*)> instead of int(*)(const char*). It will handle the return-type conversion for std::strlen (from size_t to int). Commented Apr 30, 2011 at 0:59
  • @Brian: I actually did tried something like that boost::bind(std::cout << boost::bind(_1, data) << "\n" and std::cout << (int(*)(const char*))boost::lambda::_1(data) << "\n" Commented Apr 30, 2011 at 1:01
  • @James: you are right, I made the change. Commented Apr 30, 2011 at 1:07

3 Answers 3

2

If boost::lambda and '\n' instead of endl are allowed, does the following code meet the purpose?

namespace bl = boost::lambda;
std::for_each( processors.begin(), processors.end()
             , std::cout << bl::bind( bl::_1, data ) << '\n' );
Sign up to request clarification or add additional context in comments.

3 Comments

Yes i did tried it before but there is a compile error: it looks like it is not capable to recognize the type of bl::_1.
Strange... For your information, the above code worked when I tested on VC2005 and ideone(gcc4.3.4).
You are right!, I misunderstood: boost::bind and boost::lambda::bind. It is working perfectly. Now i understand why all my previous attempt did fail.
1
void blah(int (*func)(const char *), const char *data)
{
    std::cout << func(data) << std::endl;
};

...

std::for_each(processors.begin(), processors.end(), boost::bind(blah, _1, data));

3 Comments

Thx for the answer, But i would like to avoid creating another class for this purpose.
I see..., Is it poosible to reproduce blah function using a boost::bind function ? I know it wont be really pretty. but it is for improving my understanding of boost::bind.
1

You might find it easier to use BOOST_FOREACH:

#include <vector>
#include <iostream>
#include <cstring>
#include <cstdlib>
#include <boost/foreach.hpp>
#include <boost/function.hpp>

int main()
{
    typedef boost::function<int(const char*)> ProcessorFunc;
    std::vector<ProcessorFunc> processors;
    processors.push_back(std::atoi);
    processors.push_back(std::strlen);

    const char data[] = "1.23";

    BOOST_FOREACH(ProcessorFunc& proc, processors)
    {
        std::cout << proc(data) << std::endl;
    }

}

Or you could use a ranged-based for loop from C++0x.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.