成员函数指向列表

时间:2012-03-02 09:29:39

标签: c++ foreach member-function-pointers

感谢您对以下内容发表评论。

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

目标平台:

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

问:将“std :: cout”传递给以下语句的正确方法是什么?

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

我之前在debug()函数中使用了“std :: cout”,但后来考虑为调试消息的输出提供灵活性。

编辑:更多信息:如果要运行仿函数对象,我应该如何实现仿函数来处理多个类(这些类除了相同的“调试”函数签名之外没有任何关系)?

编辑(2):使用“std :: for_each”,是否可以通过直接为每个类调用相应的析构函数来销毁list1中的所有对象? (例如for_each(l.begin(),l.end(),“Class :: ~Class1”);

编辑(3):根据建议的“pmr”,我将声明作为

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

它在linux平台上编译并运行正常,但在VS2010上失败了,Class1 :: debug的代码是

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

VS错误消息是

错误C2678:二进制'&lt;&lt;' :找不到哪个运算符带有'const std :: ostream'类型的左手操作数(或者没有可接受的转换)

任何提示?

[关闭] 我现在实现了重载运算符&lt;&lt;对于我的类,并且关闭调试打印功能的使用。非常感谢所有提示。

4 个答案:

答案 0 :(得分:1)

由于您使用的是g ++ 4.4,因此不能使用首选的lambda表达式(后来的版本支持它们,MSVC也支持它们)。

所以你需要一个仿函数。仿函数是一个函数对象,它是一个实现operator()的类(或结构)。像这样:

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;
};

像这样使用:

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

答案 1 :(得分:0)

使用lambda而不是函数指针。这是C ++ 11x的一个特性,您需要包含一个标志,以便编译器识别lambda。

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

答案 2 :(得分:0)

由于GCC在4.5之前不支持lambdas,因此无法提供最清晰的解决方案。

当您想要使用大量通用算法时,第二个最简单的解决方案是Boost.Lambda http://www.boost.org/doc/libs/1_49_0/doc/html/lambda.html

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

最后,繁琐的仿函数解决方案:

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));

就我个人而言,我认为没有C ++ 11 lambdas或Boost Lambdas,for_each比它的价值更痛苦。不妨做一个简单的循环:

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

答案 3 :(得分:0)

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;
}

请注意,粘合剂已弃用且boost::bind或 C ++ 11应该受到青睐。你应该真的得到一个更新的编译器。