成员函数指针列表

问题描述:

谢谢你给意见如下。成员函数指针列表

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

目标平台:

  • 平台(1):运7x64,VS2010
  • 平台(2):Linux的32倍,克++ 4.4

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

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

我以前使用的“性病::法院”调试()函数内部,但后来考虑到给灵活性调试信息的输出。

编辑:更多信息:如果仿的对象是要走的路,应该怎么实现函子,以应付多个类(这些类,除了有相同的“调试”函数签名没有关系)?

编辑(2):使用“的std :: for_each的”,是有可能通过调用相应的析构函数直接每个类摧毁list1的所有对象? (如的for_each(l.begin(),l.end(), “类::〜1类”);

编辑(3):按照 “PMR” 的建议,我让语句

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

它编译和正确地在Linux平台上运行,但未能在VS2010中,代码的Class1 ::调试是

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

的VS错误味精是

错误C2678:二进制 '< <':没有操作ATOR发现它接受一个左边的操作数类型“常量性病的ostream ::”的(或不存在可接受的转化率)

任何线索?

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

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

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

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

由于GCC不支持lambda表达式,直到4.5,最明显的解决方案是不可能的。

当你想使用很多通用算法的第二个最简单的解决方法是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); 

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

+0

我遵循你的建议,它编译到一些点,但它在MS VS2010失败,抛出错误“错误C2678:二进制' 2012-03-05 03:03:18

+0

我在示例代码中看不到任何'operator pmr 2012-03-05 09:27:04