help in solving this function object.

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • learning

    #1

    help in solving this function object.

    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::stri ng s, std::string name){
    std::filebuf buffer;
    std::ostream output(&buffer) ;
    buffer.open(nam e.c_str(), std::ios::out);
    output << s << std::endl;
    }
    };

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

    for_each(lStrin g.begin(),lStri ng.end(),apply( ));
    return 0;
    }

  • tolgaceylanus@yahoo.com

    #2
    Re: help in solving this function object.


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

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

    2) Your definition of makefile::opera tor() 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(lStrin g.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

    Comment

    • learning

      #3
      Re: help in solving this function object.


      tolgaceylanus@y ahoo.com wrote:
      Code needs a lot of help, but the biggest problems are;
      >
      1) for_each expects a function object that takes one param, while
      makefile::opera tor() expects 2 params. No matching func...
      >
      2) Your definition of makefile::opera tor() 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(lStrin g.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

      Comment

      • Thomas J. Gritzan

        #4
        Re: help in solving this function object.

        learning schrieb:
        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::stri ng 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()(cons t std::string& name)
        std::filebuf buffer;
        std::ostream output(&buffer) ;
        buffer.open(nam e.c_str(), std::ios::out);
        output << s << std::endl;
        Why don't you use a simple ofstream object?

        std::ofstream output(name.c_s tr());
        output << s << std::endl;
        }
        };
        >
        int main(){
        std::string s("1234567890") ;
        std::string al("abc");
        list<std::strin glString;
        for (int i=0; i <= 9; i++) {
        //std::string tmp(itoa(i));
        al = s+ s.at(i);
        What is 'al' for?
        lString.push_ba ck(s);
        }
        //for_each();
        >
        for_each(lStrin g.begin(),lStri ng.end(),apply( ));
        for_each(lStrin g.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()(cons t std::pair<std:: string, std::string>& record) const
        {
        std::ofstream file(record.fir st.c_str());
        file << record.second << std::endl;
        }
        }

        --
        Thomas

        Comment

        • Daniel T.

          #5
          Re: help in solving this function object.

          In article <1156885518.441 249.327490@p79g 2000cwp.googleg roups.com>,
          "learning" <edwardt.tril@g mail.comwrote:
          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() );
          }

          Comment

          • Daniel T.

            #6
            Re: help in solving this function object.

            "learning" <edwardt.tril@g mail.comwrote:
            >
            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.

            Comment

            • learning

              #7
              Re: help in solving this function object.


              Thomas J. Gritzan wrote:
              learning schrieb:
              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::stri ng 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()(cons t std::string& name)
              >
              std::filebuf buffer;
              std::ostream output(&buffer) ;
              buffer.open(nam e.c_str(), std::ios::out);
              output << s << std::endl;
              >
              Why don't you use a simple ofstream object?
              >
              std::ofstream output(name.c_s tr());
              output << s << std::endl;
              >
              }
              };

              int main(){
              std::string s("1234567890") ;
              std::string al("abc");
              list<std::strin glString;
              for (int i=0; i <= 9; i++) {
              //std::string tmp(itoa(i));
              al = s+ s.at(i);
              >
              What is 'al' for?
              >
              lString.push_ba ck(s);
              }
              //for_each();

              for_each(lStrin g.begin(),lStri ng.end(),apply( ));
              >
              for_each(lStrin g.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()(cons t std::pair<std:: string, std::string>& record) const
              {
              std::ofstream file(record.fir st.c_str());
              file << record.second << std::endl;
              }
              }
              >
              --
              Thomas
              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>.t xt where <1is 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(lStrin g.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(lStrin g.begin(),lStri ng.end(),makefi le(al)); or
              for_each(lStrin g.begin(),lStri ng.end(),makefi le());
              or are there some other tricks?
              Thanks

              Comment

              Working...