|
-
November 21st, 2011, 01:45 AM
#1
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.
-
November 21st, 2011, 09:27 AM
#2
Re: std::for_each is not compiling with boost::algorithm::to_lowe
 Originally Posted by code_carnage
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.
-
November 21st, 2011, 10:12 AM
#3
Re: std::for_each is not compiling with boost::algorithm::to_lowe
 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
-
November 21st, 2011, 11:38 AM
#4
Re: std::for_each is not compiling with boost::algorithm::to_lowe
 Originally Posted by Joeman
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
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|