help in solving this function object.

L

learning

I am trying to learn STL but got stuck in for_each().
What I intend to do in the following is to make a list with each
element as a string.
add the string elements to the list until it has 10 elements. each
element is the same 1234567890. then I want to use for_each to iterate
the list, and for each to call apply() whihc is create a filen with
name the same as string al; and within each file, it contains the
content of the list element.
I go stuck in making apply to work. Can anyone help?? the following is
the code, it compiles under vc++ 8.


Thanks


#include <algorithm>
#include <list>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

class makefile{

public:
void operator()(std::string sth, std::string sth2){

};
void apply(std::string s, std::string name){
std::filebuf buffer;
std::eek:stream output(&buffer);
buffer.open(name.c_str(), std::ios::eek:ut);
output << s << std::endl;
}
};

int main(){
std::string s("1234567890");
std::string al("abc");
list<std::string> lString;
for (int i=0; i <= 9; i++) {
//std::string tmp(itoa(i));
al = s+ s.at(i);
lString.push_back(s);
}
//for_each();

for_each(lString.begin(),lString.end(),apply());
return 0;
}
 
T

tolgaceylanus

Code needs a lot of help, but the biggest problems are;

1) for_each expects a function object that takes one param, while
makefile::eek:perator() expects 2 params. No matching func...

2) Your definition of makefile::eek:perator() does not call
makefile::apply() at all. operator() is empty. You seem to
misunderstand
function objects. In your code, makefile::apply() never gets called.

3) you don't have an instance of makefile class. You need to
instantiate and
get an object. Something like;

makefile my_obj;
for_each(lString.begin(), lString.end(), my_obj);

(Note that it's my_obj, not my_obj() above...)

for_each will call my_obj() which would execute operator() in your
makefile class.

Hope this helps,

Tolga Ceylan
 
L

learning

Code needs a lot of help, but the biggest problems are;

1) for_each expects a function object that takes one param, while
makefile::eek:perator() expects 2 params. No matching func...

2) Your definition of makefile::eek:perator() does not call
makefile::apply() at all. operator() is empty. You seem to
misunderstand
function objects. In your code, makefile::apply() never gets called.

3) you don't have an instance of makefile class. You need to
instantiate and
get an object. Something like;

makefile my_obj;
for_each(lString.begin(), lString.end(), my_obj);

(Note that it's my_obj, not my_obj() above...)

for_each will call my_obj() which would execute operator() in your
makefile class.

Hope this helps,

Tolga Ceylan
Thanks Tolga.
So what should I do if the operation that I apply to each element of
the list needs 2 input parameters?
If I change the makefile object to take 1 parameter -- std:string for
each element in a list, but I also need the client have a say to change
the filename of the output file. Can I archieve this using for_each? I
can make the whoe thing with a for-loop, but I am trying to see if
for_each or other tools inside algorithm can do the trick for me.
Thanks
 
T

Thomas J. Gritzan

learning said:
I am trying to learn STL but got stuck in for_each().
What I intend to do in the following is to make a list with each
element as a string.
add the string elements to the list until it has 10 elements. each
element is the same 1234567890. then I want to use for_each to iterate
the list, and for each to call apply() whihc is create a filen with
name the same as string al; and within each file, it contains the
content of the list element.
I go stuck in making apply to work. Can anyone help?? the following is
the code, it compiles under vc++ 8.

It doesn't compile.
Thanks


#include <algorithm>
#include <list>
#include <iostream>
#include <fstream>
#include <string>
#include <cstdlib>

using namespace std;

class makefile{

public:
void operator()(std::string sth, std::string sth2){

};
void apply(std::string s, std::string name){

Put this code in operator().

for_each supplies only one argument, so it should be:

void operator()(std::string name) // or:
void operator()(const std::string& name)
std::filebuf buffer;
std::eek:stream output(&buffer);
buffer.open(name.c_str(), std::ios::eek:ut);
output << s << std::endl;

Why don't you use a simple ofstream object?

std::eek:fstream output(name.c_str());
output << s << std::endl;
}
};

int main(){
std::string s("1234567890");
std::string al("abc");
list<std::string> lString;
for (int i=0; i <= 9; i++) {
//std::string tmp(itoa(i));
al = s+ s.at(i);

What is 'al' for?
lString.push_back(s);
}
//for_each();

for_each(lString.begin(),lString.end(),apply());

for_each(lString.begin(), lString.end(), makefile());
return 0;
}

Your makefile() functor opens a file with name given to it and outputs a
string given as second argument. for_each can only work with one element at
a time.
If you want multiple files with different output strings, try a
std::list< std::pair<std::string, std::string> >
with first string being the filename and second string the text to output.

The functor would be like this:

struct makefile
{
void operator()(const std::pair<std::string, std::string>& record) const
{
std::eek:fstream file(record.first.c_str());
file << record.second << std::endl;
}
}
 
D

Daniel T.

"learning said:
I am trying to learn STL but got stuck in for_each().
What I intend to do in the following is to make a list with each
element as a string.
add the string elements to the list until it has 10 elements. each
element is the same 1234567890. then I want to use for_each to iterate
the list, and for each to call apply() whihc is create a filen with
name the same as string al; and within each file, it contains the
content of the list element.
I go stuck in making apply to work. Can anyone help?? the following is
the code, it compiles under vc++ 8.

Really? It compiles? If so then you need to throw away your compiler.

struct makefile
{
void operator()( const string& s ) const {
// here you want to "create a filen with name the same as string
// al; and within each file, it contains the content of the list
// element."
// are you sure you want to create the same file over and over
// again though?
}
};

int main()
{
list< string > strings;
// fill 'strings'
for_each( strings.begin(), strings.end(), makefile() );
}
 
D

Daniel T.

learning said:
So what should I do if the operation that I apply to each element
of the list needs 2 input parameters?

Where are those parameters coming from?
If I change the makefile object to take 1 parameter -- std:string
for each element in a list, but I also need the client have a say
to change the filename of the output file. Can I archieve this
using for_each?

Do you want each element to have a different value for the second
parameter or the same value? Where is the value or values coming from?
I can make the whoe thing with a for-loop, but I am trying to see
if for_each or other tools inside algorithm can do the trick for me.

Show us a for loop so we can see what you are trying to accomplish. It
may be that 'for_each' is not the best tool for the job.
 
L

learning

Thomas said:
It doesn't compile.


Put this code in operator().

for_each supplies only one argument, so it should be:

void operator()(std::string name) // or:
void operator()(const std::string& name)


Why don't you use a simple ofstream object?

std::eek:fstream output(name.c_str());
output << s << std::endl;


What is 'al' for?


for_each(lString.begin(), lString.end(), makefile());


Your makefile() functor opens a file with name given to it and outputs a
string given as second argument. for_each can only work with one element at
a time.
If you want multiple files with different output strings, try a
std::list< std::pair<std::string, std::string> >
with first string being the filename and second string the text to output.

The functor would be like this:

struct makefile
{
void operator()(const std::pair<std::string, std::string>& record) const
{
std::eek:fstream file(record.first.c_str());
file << record.second << std::endl;
}
}

I was thinking about using "string al" as the filename and "string s",
each list element is a string s, and the play program uses that as the
file content.

My original intention was to change the list element too, but just
leave it this way to make the for_each works first.

so let's say list has 10 elements, each of which is a string:
1234567890 and after the action applied under the for_each (or other
mechanism)..
the filename will be the
1234567890<1>.txt where <1> is the counter (the <> will not appear in
the filename, just mark here for clairty)
so the expected result will have 10 files:
12345678901.txt
12345678902.txt ....
all has 1234567890 as file content. As you are seeing, I am clearly
weak in STL and good c++.

So further questions on your post:
My original throught was somethign like:
for_each(lString.begin(), lString.end(), makefile(al)); <<---- of
course this does not compile, so I need to take away the al and make
makefile(); .. I am more confused by the std::pair .. how can this
functor be called from for_each?

I think I am not clear about that that are you saying the modified
functor makefile WONT work with for_each because of the restriction for
1 argument functor ? Or that the new modified one WILL work with
for_each?
I don't think the following will compile:
for_each(lString.begin(),lString.end(),makefile(al)); or
for_each(lString.begin(),lString.end(),makefile());
or are there some other tricks?
Thanks
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,183
Messages
2,570,967
Members
47,518
Latest member
RomanGratt

Latest Threads

Top