指向指针列表的成员函数

Member function to a list of pointer

本文关键字:成员 函数 列表 指针      更新时间:2023-10-16

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

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",但后来考虑为调试消息的输出提供灵活性。

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

Edit(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;':找不到接受类型为"const-std::ostream"的左侧操作数的运算符(或者没有可接受的转换)

有线索吗?

[已关闭]我现在实现了重载运算符<lt;对于我的类,调试打印函数的使用是关闭的。非常感谢所有的提示。

由于您使用的是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);

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

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

由于GCC在4.5之前不支持lambdas,因此不可能找到最清晰的解决方案。

当你想使用很多通用算法时,第二个最简单的解决方案是Boost.Lambdahttp://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);

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应该受到青睐。你真的应该有一个更新的编译器。