CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Results 1 to 4 of 4
  1. #1
    Join Date
    May 2007
    Location
    Bangalore India
    Posts
    262

    std::for_each is not compiling with boost::algorithm::to_lowe

    Hello,
    Do you guys know why this does not compile?
    <code>
    std::for_each(v.begin(), v.end(), &boost::algorithm::to_lower<string>);
    </code>
    v is a vector of strings that I want to convert to lowercase.
    However, if I have another function
    Code:
    static  void toLowerCase(string &s) 
    {
         boost::algorithm::to_lower<string>(s);
    }
    and do like the following it works..
    Code:
    std::for_each(v.begin(), v.end(), toLowerCase);
    compiler is g++
    Thanks in advance
    -Prashant
    Dont forget to rate my post if you find it useful.

  2. #2
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: std::for_each is not compiling with boost::algorithm::to_lowe

    Quote Originally Posted by code_carnage View Post
    Hello,
    Do you guys know why this does not compile?
    <code>
    std::for_each(v.begin(), v.end(), &boost::algorithm::to_lower<string>);
    </code>
    v is a vector of strings that I want to convert to lowercase.
    However, if I have another function
    Code:
    static  void toLowerCase(string &s) 
    {
         boost::algorithm::to_lower<string>(s);
    }
    and do like the following it works..
    Code:
    std::for_each(v.begin(), v.end(), toLowerCase);
    compiler is g++
    Thanks in advance
    -Prashant
    to_lower takes a second default std::locale argument. The problem is that you are passing a function pointer as an argument, which strips the default parameters (default parameters are determined at compile time, and function pointers are compile-time objects). Hence the "too few arguments" error.

    For the algorithm to work, you'd need to wrap to_lower in a "function object". Theory would instruct you to try to use std::bind/std::function. However, I feel that the resulting code is so obscure/convoluted, you are better off doing it by hand

    I'd love to see someone show me how it's done: I failed

    In the mean time, you can either use your toLowerCase function, or write a function object:

    Code:
    #include <string>
    #include <algorithm>
    #include <boost/algorithm/string/case_conv.hpp>
    #include <locale>
    
    template<typename T>
    struct to_lower_functor
    {
      void operator()(T& i, const std::locale& Loc = std::locale()) const
      {
        return boost::algorithm::to_lower<T>(i, Loc);
      }
    };
    
    int main()
    {
      std::vector<std::string> v;
      std::for_each(v.begin(), v.end(), to_lower_functor<std::string>());
    }
    Last edited by monarch_dodra; November 21st, 2011 at 09:30 AM.
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

  3. #3
    Join Date
    Jun 2008
    Posts
    592

    Re: std::for_each is not compiling with boost::algorithm::to_lowe

    Quote Originally Posted by monarch_dodra
    Theory would instruct you to try to use std::bind/std::function. However, I feel that the resulting code is so obscure/convoluted, you are better off doing it by hand

    I'd love to see someone show me how it's done: I failed
    Code:
    #include <functional> 
    #include <algorithm> 
    #include <vector>
    #include <string>
    #include <locale>
    
    #include <boost/algorithm/string/case_conv.hpp> 
    
    using namespace std;
    using namespace placeholders;
    
    int main()
    {
    	vector< string > Array; 
    	for_each( Array.begin(), Array.end(), bind( &boost::algorithm::to_lower< string >, _1, locale() ) );
    
    	return 0;
    }
    I don't have boost to make sure that is right, but I am pretty confident.
    Last edited by Joeman; November 21st, 2011 at 10:28 AM.
    0100 0111 0110 1111 0110 0100 0010 0000 0110 1001 0111 0011 0010 0000 0110 0110 0110 1111 0111 0010
    0110 0101 0111 0110 0110 0101 0111 0010 0010 0001 0010 0001 0000 0000 0000 0000
    0000 0000 0000 0000

  4. #4
    Join Date
    Jun 2009
    Location
    France
    Posts
    2,513

    Re: std::for_each is not compiling with boost::algorithm::to_lowe

    Quote Originally Posted by Joeman View Post
    Code:
    #include <functional> 
    #include <algorithm> 
    #include <vector>
    #include <string>
    #include <locale>
    
    #include <boost/algorithm/string/case_conv.hpp> 
    
    using namespace std;
    using namespace placeholders;
    
    int main()
    {
    	vector< string > Array; 
    	for_each( Array.begin(), Array.end(), bind( &boost::algorithm::to_lower< string >, _1, locale() ) );
    
    	return 0;
    }
    I don't have boost to make sure that is right, but I am pretty confident.
    >:(

    That's why it wasn't working for me: I was using _2... I keep forgetting the the index of "first" is 0, and the index of "second" is 1. The worst part is I had tried that exact piece of code...

    Stupid std::pair and "bind1st"/"bind2nd" teaching me wrong.
    --------
    There is one thing that bothers me though (in both versions): Explicit re-statement of a default parameter. Anybody know of a way to keep the second parameter, without hand-copying the default constructor?
    Is your question related to IO?
    Read this C++ FAQ article at parashift by Marshall Cline. In particular points 1-6.
    It will explain how to correctly deal with IO, how to validate input, and why you shouldn't count on "while(!in.eof())". And it always makes for excellent reading.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured