Member function to a list of pointer

主宰稳场 提交于 2019-12-11 11:18:25

问题


Thanks for giving comments to the following.

Class1 { debug(std::ostream&){} };
int main() {
  std::vector<Class1*> list1;
  // some work to do
}

Target Platform:

  • Platform(1): Win 7x64, VS2010
  • Platform(2): Linux x32, g++ 4.4

Q: What should be the correct way to pass "std::cout" to following statement?

std::for_each(list1.begin(), 
              list1.end(), 
              "afunction(&Class1::debug, std::cout)");

I previously used "std::cout" inside the debug() function, but later consider to give flexibility for the output of debug message.

Edit: More information: if functor objects is the way to go, how should I implements the functor to cope with multiple classes (those classes have no relationship except the same "debug" function signature)?

Edit(2): Using "std::for_each", is it possible to destroy all objects in list1 by invoking the corresponding destructor for each class directly? (e.g. for_each(l.begin(), l.end(), "Class::~Class1");

Edit(3): As per "pmr" suggested, I make the statement as

std::for_each(l.begin(), 
              l.end(), 
              std::bind2nd(std::mem_fn(&Class1::debug), out) );

It compiles and run correctly on linux platform, but failed on VS2010, the code for Class1::debug is

void Class1::debug(const std::ostream& out)
{ 
    out << "some text" << someVar << "some text" << std::endl; 
}

The VS error msg is

error C2678: binary '<<' : no operator found which takes a left-hand operand of type 'const std::ostream' (or there is no acceptable conversion)

Any cue?

[Closed] I now implemented the overloaded operator << for my classes, and the use of debug print function is closed. Thanks very much for all hints given.


回答1:


Since you are using g++ 4.4 you can't use lambda expressions which would be the first choice (later versions support them, MSVC does as well).

So you need a functor. A functor is a function object, that is a class (or struct) that implements operator(). Like this:

class Debug
{
public:
     Debug(ostream& os) : _os(os)
     { }

     void operator()(Class1* instance)
     {
          // will print the pointer, replace with user code
          os << instance << endl;
     }
private:
     ostream& _os;
};

Use like this:

 Debug d(cout);
 std::for_each(list1.begin(), list1.end(), d);



回答2:


use lambda instead of function pointers. This is a feature of C++11x and you need to include a flag for compiler to recognise lambda.

   std::for_each(list1.begin(), list1.end(), [&debug, &cout]
{
// implementaion
}
);



回答3:


As GCC does not support lambdas until 4.5, the clearest solution is out of the question.

The second easiest solution when you want to use a lot of generic algorithms is Boost.Lambda http://www.boost.org/doc/libs/1_49_0/doc/html/lambda.html:

for_each(list1.begin(), list.end(), _1->debug(cout));

And finally, the tedious functor solution:

class Output
{
public:
     explicit Output(ostream& ios) : os(&ios)
     {
     }

     void operator()(Class1* obj)
     {
          obj->debug(*os);
     }

private:
     ostream* os;
};
for_each(list1.begin(), list1.end(), Output(cout));

Personally I think that without C++11 lambdas or Boost Lambdas, for_each is more pain than it's worth. Might as well do a simple loop:

for (vector<Class1*>::iterator it = list1.begin(); it != end; ++it)
    (*it)->debug(cout);



回答4:


C++03:

#include <vector>
#include <functional>
#include <iostream>
#include <algorithm>

struct Foo {
  void debug(std::ostream&) {}
};

int main()
{
  std::vector<Foo*> foos;
  std::for_each(foos.begin(), foos.end(), 
                std::bind2nd(std::mem_fun(&Foo::debug), std::cout));
  return 0;
}

Please note that the binders have been deprecated and boost::bind or C++11 should be favored. You should really get a newer compiler.



来源:https://stackoverflow.com/questions/9530859/member-function-to-a-list-of-pointer

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!