【发布时间】:2017-11-29 12:51:20
【问题描述】:
我对在 C++ 中使用 algorithm 和 functional 还很陌生。我需要进行树遍历并为每个元素执行一个功能。请参阅下面的代码。
这可行,但我有一些我不喜欢的东西,也许可以做得更好。请注意,我仅限于 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;
}
【问题讨论】:
-
我认为寻求工作代码反馈的问题通常应该发布在 Code Review 上,而不是 SO。
-
@underscore_d 我可以想象这两者都适用,因为它正在询问有关语言功能的特定问题,该功能无法按预期工作(即使问题中存在解决方法) .
-
你可以使用
std::bind(&Elem::walk, std::placeholders::_1, f));,所以你不需要do_walk -
for range (C++11) 是
for_each->for (auto& elem : children) { elem.walk(f); }的一个很好的替代品。它应该在 gcc 4.4.7 中启用 -
:/, 所以
for (auto it = children.begin(); it != children.end(); ++it) {it->walk(f);}.