boost :: visit_each有什么用?

时间:2011-07-09 01:11:01

标签: c++ boost

我读了documentation on visit_each,但是如果每个用户都不得不重载它,就无法真正看到它究竟是什么以及它的一般用途。有人关心开导我吗?


编辑:也许我只是感到困惑,因为以下是<boost/visit_each.hpp>的全部内容,我只是看不到“访问每个子对象”的任何“魔力” :

namespace boost {
  template<typename Visitor, typename T>
  inline void visit_each(Visitor& visitor, const T& t, long)
  {
    visitor(t);
  }

  template<typename Visitor, typename T>
  inline void visit_each(Visitor& visitor, const T& t)
  {
    visit_each(visitor, t, 0);
  }
}

也许有人可以给我一个具体的例子来说明这应该是什么样的/工作?

3 个答案:

答案 0 :(得分:2)

我想这可能会更有帮助:

Design Overview - visit_each function template

答案 1 :(得分:1)

我怀疑该文档的重要部分是这一行:“图书馆作者需要添加额外的重载,专门针对他们的类的T参数,以便可以访问子对象。”换句话说,它没有一般用途,它只是任何基于访问者的内省机制的通用名称。它的实现方式,某些将发生在所有类型中,无论它们的编写者是否知道它的存在,因此您不会遇到编译时失败。

它对我来说似乎没什么用处......实际上,它只是增强信号库的内部功能,但我想如果你使用那个库,无论如何专注于visit_each你自己类型不会受到伤害。

他们提到找到signals::trackable个对象。因此,据推测,他们在信号库中为自己的类型提供了几个特化。然后他们有一个is_trackable仿函数。或类似的东西。

struct trackable { };

struct Introspective {
    int a;
    double b;
    trackable c;
};

struct NotIntrospective {
    int a;
    double b;
    trackable c;
};

template<typename Visitor, typename T>
inline void visit_each(Visitor& visitor, const T& t, long) {
  visitor(t);    
} 

template<typename Visitor>
inline void visit_each(Visitor& visitor, const Introspective& t, int) {
  visitor(t); //"visits" the object as a whole

  //recursively visit the member objects; if unspecialized, will simply call `visitor(x)`
  visit_each(visitor, t.a, 0);
  visit_each(visitor, t.b, 0);
  visit_each(visitor, t.c, 0);
}

struct is_trackable {
  void operator()(const trackable&) { 
    //Do something
  }

  template<typename T>
  void operator()(const T&) { }
}

int main() {
    Introspective a;
    NotIntrospective b;
    trackable c;

    visit_each(is_trackable(), a, 0); //calls specialized version, finds `a.c`
    visit_each(is_trackable(), b, 0); //calls default version, finds nothing
    visit_each(is_trackable(), c, 0); //calls default version, which "visits" the 
                                      //object itself, and finds that it is trackable
}

关键是visit_each本身没有做任何魔术,除了提供一种调用visit_each以便无法在无法识别的类型上编译的方法。

答案 2 :(得分:0)

visit_each 允许检查受 boost::bind 约束的变量。规范示例是检查 this 指针的内容并从中提取基数 boost::signals::trackable

class MyClass : boost::signals::trackable
{
    void my_method(int arg);
}

boost::signal<void()> signal;

signal.connect( boost::bind(&MyClass::my_method, this, 5) );

这样,boost::signal 就可以完成对 MyClass 对象的安全回调订阅。