for_each, bind2nd and mem_fun_ref

This is a discussion on for_each, bind2nd and mem_fun_ref within the C++ Programming forums, part of the General Programming Boards category; First off I am using either MSVC++ 6.0 or MS.NET on a C++ console application. I have some code that ...

  1. #1
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788

    for_each, bind2nd and mem_fun_ref

    First off I am using either MSVC++ 6.0 or MS.NET on a C++ console application. I have some code that uses the for_each function to print out some data on a set of objects using the mem_fun_ref adapter to call the object's own print function. This all works fine if the object's print function doesn't have any parameters and can internally just use a specific output stream, cout for example:
    Code:
    #include <set>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    using namespace std;
    
    class tsv
    {
    public:
        // BTW... for .NET the function below works, but...
        // MSVC++ however insists on a non-const func returning a value in the for_each call below
        void print() const
        {
            // Output class data to cout for example
        }
    };
    
    int main()
    {
        set<tsv> TsvSet;
    
        // Read in multiple tsv objects and insert them into the set
    
        // Now use for_each and tsv object's own print function for output to cout
    
        for_each( TsvSet.begin(), TsvSet.end(), mem_fun_ref(tsv::print) ); // Works just fine
    
        return 0;
    }
    What I want to have happen is to be able to have the object's print function accept a parameter to an ostream stream object so I could have my for_each function either output everything to cout for example at one point in the program or later output something to a file. I have been looking through Nicolai Josuttis' The C++ Standard Library: A Tutorial and Reference (8.2.2 Function Adapters for Member Functions) and he seems to say you can pass a single parameter to a function in this manner using bind2nd. For example:
    Code:
    #include <set>
    #include <iostream>
    #include <algorithm>
    #include <functional>
    #include <fstream>
    using namespace std;
    
    class tsv
    {
    public:
        void print(ostream& out) const
        {
            // Output class data to "out" ostream object
        }
    };
    
    int main()
    {
        set<tsv> TsvSet;
        ofstream outfile("Output.Txt");
    
        // Read in multiple tsv objects and insert them into the set
    
        // Now use for_each and tsv object's own print function for output to outfile...
        // This does not work for me.
    
        for_each( TsvSet.begin(), TsvSet.end(), bind2nd(mem_fun_ref(tsv::print),outfile) );
    
        return 0;
    }
    In .NET I seem to get "reference-to-a-reference" errors using the bind2nd function, in MSVC++ I think I get "cannot deduce template argument" errors. Is there some trick I need to get this working? I have tried making the parameter const/non-const, reference/non-reference, this/that and it's starting to frustrate me. Either there is something simple I'm missing or I can't do this in this fashion. I can get around this by having my print function in a zero argument manner to print to a static ofstream member of my tsv class so that the for_each function can write all the objects to the same file but I would like to know if this at least possible.
    Last edited by hk_mp5kpdw; 04-09-2004 at 07:38 AM. Reason: Added "public:" to tsv class
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

  2. #2
    Code Goddess Prelude's Avatar
    Join Date
    Sep 2001
    Posts
    9,796
    The only way I could get it to work after a few minutes was to have print take a pointer to an ostream instead of a reference. If you use a reference then bind2nd creates its own reference, resulting in a reference to a reference, which is illegal.
    My best code is written with the delete key.

  3. #3
    Registered User hk_mp5kpdw's Avatar
    Join Date
    Jan 2002
    Location
    Northern Virginia/Washington DC Metropolitan Area
    Posts
    3,788
    Thanks, I will try messing around with that and see if I can get it to work.
    "Owners of dogs will have noticed that, if you provide them with food and water and shelter and affection, they will think you are god. Whereas owners of cats are compelled to realize that, if you provide them with food and water and shelter and affection, they draw the conclusion that they are gods."
    -Christopher Hitchens

Popular pages Recent additions subscribe to a feed

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21