我是相当新的使用algorithm和functionalC++中.我需要进行树遍历并为每个元素执行一个函数.请参阅下面的代码.
这有效,但我有一些我不喜欢的事情,或许可以做得更好.请注意,我仅限于相当旧版本的g ++(4.4.7),并且不能使用lambda函数.
我使用包装函数do_walk并在每个元素上std::bind调用成员函数walk.有没有办法避免包装函数并直接调用成员函数?
我使用typedef作为回调函数UnaryFunction.我更喜欢使用模板版本walk.但是,当我更改代码以使用模板时,我得到以下编译错误:error: no matching function for call to 'bind(<unresolved overloaded function type>, std::_Placeholder<1>&, void (*&)(const Elem&))'.是否可以在此上下文中使用模板?
也许有一种替代方案std::for_each更适合这种树遍历?
我的代码到目前为止:
#include <list>
#include <algorithm>
#include <functional>
struct Elem;
typedef void (*UnaryFunction)(const Elem&); // (2)
struct Elem
{
std::list<Elem> children; // Some container, std::list for now.
//template< class UnaryFunction > // (2)
void walk(UnaryFunction f) const
{
// Walk all children.
std::for_each(
children.begin(),
children.end(),
std::bind(do_walk, std::placeholders::_1, f)); // (1)
// Walk this object.
f(*this);
}
//template< class UnaryFunction > // (2)
static void do_walk(const Elem& elem, UnaryFunction f) // (1)
{
elem.walk(f);
}
};
void pretty_print(const Elem& elem)
{
// Pretty print element.
}
int main()
{
Elem root;
// Create tree somehow.
root.walk(pretty_print);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
std::bind能够调用成员函数(将第一个参数传递给隐式this参数),因此您可以替换do_walk为:
std::bind(&Elem::walk, std::placeholders::_1, f)
Run Code Online (Sandbox Code Playgroud)制作walk模板的问题在于,在进行时,bind不清楚应该使用哪个实例化.您可以通过显式指定模板参数来消除歧义:
std::bind(&Elem::walk<UnaryFunction>, std::placeholders::_1, f)
Run Code Online (Sandbox Code Playgroud)我相信std::for_each很好.
[实例]使用gcc 4.4.7
| 归档时间: |
|
| 查看次数: |
192 次 |
| 最近记录: |