boost::visit_each的用途是什么?

What is the use of boost::visit_each?

本文关键字:是什么 each visit boost      更新时间:2023-10-16

我阅读了关于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);
  }
}

也许有人可以给我一个具体的例子,这应该看起来像/工作?

我想这可能更有帮助:

设计概述- visit_each函数模板

我怀疑该文档的重要部分是这一行:"库作者将被期望添加额外的重载来专门化其类的T参数,以便可以访问子对象。"换句话说,它没有一般用途,它只是任何基于访问者的内省机制的通用名称。它的实现方式是,一些将发生在所有类型上,无论它们的作者是否意识到它的存在,所以您不会得到编译时失败。

对我来说似乎没有太大的用处……实际上,它只是boost信号库的一个内部函数,但是我想,如果您正在使用该库,无论如何,将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的调用不会在无法识别的类型上编译失败。

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对象的安全回调订阅。