boost::any 的访问者模式

2023-11-23

我找到了这个https://gist.github.com/2945472但我需要一个不依赖于 c++11 的实现。我尝试将其转换为仅使用升压,但遇到了一些麻烦。

这是我想出的:

#include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/unordered_map.hpp>

struct type_info_hash {
    std::size_t operator()(std::type_info const & t) const {
        return t.hash_code();
    }
};

struct equal_ref {
    template <typename T> bool operator()(boost::reference_wrapper<T> a,boost::reference_wrapper<T> b) const {
        return a.get() == b.get();
    }
};
struct any_visitor {
    boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref> fs;

    template <typename T> void insert_visitor(boost::function<void(T)> f) {
        try {
            fs.insert(std::make_pair(boost::ref(typeid(T)), boost::bind(f, boost::any_cast<T>(boost::lambda::_1))));
        } catch (boost::bad_any_cast& e) {
            std::cout << e.what() << std::endl;
        }
    }

    bool operator()(boost::any & x) {
        boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref>::iterator it = fs.find(boost::ref(x.type()));
        if (it != fs.end()) {
            it->second(x);
            return true;
        } else {
            return false;
        }
    }
};

struct abc {};

void fa(int i) { std::cout << "fa(" << i << ")" << std::endl; }
void fb(abc) { std::cout << "fb(abc())" << std::endl; }

int main() {
    any_visitor f;
    f.insert_visitor<int>(fa);
    f.insert_visitor<abc>(fb);

    std::vector<boost::any> xs;
    xs.push_back(1);
    xs.push_back(abc());
    xs.push_back(1.5);

    for (auto & x : xs) {
        if (!f(x)) std::cout << "no visitor registered" << std::endl;
    }
}

插入地图时出现 bad_any_cast 。 any_cast 不应该只由 it->second(x) 调用吗?我究竟做错了什么?


你无法投射_1 to T(在绑定表达式时)。

你需要一个懒惰的演员。也许定义一个函数并使用嵌套绑定表达式,或者将 Boost Phoenix 与自定义函数一起使用any_cast actor.

这是嵌套绑定方法:

#include <boost/any.hpp>
#include <boost/function.hpp>
#include <boost/bind.hpp>
#include <boost/lambda/lambda.hpp>
#include <boost/unordered_map.hpp>

struct type_info_hash {
    std::size_t operator()(std::type_info const & t) const {
        return 42; // t.hash_code();
    }
};

struct equal_ref {
    template <typename T> bool operator()(boost::reference_wrapper<T> a,boost::reference_wrapper<T> b) const {
        return a.get() == b.get();
    }
};
struct any_visitor {
    boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref> fs;

    template <typename T> static T any_cast_f(boost::any& any) { return boost::any_cast<T>(any); }

    template <typename T> void insert_visitor(boost::function<void(T)> f) {
        try {
            fs.insert(std::make_pair(boost::ref(typeid(T)), boost::bind(f, boost::bind(any_cast_f<T>, boost::lambda::_1))));
        } catch (boost::bad_any_cast& e) {
            std::cout << e.what() << std::endl;
        }
    }

    bool operator()(boost::any & x) {
        boost::unordered_map<boost::reference_wrapper<std::type_info const>, boost::function<void(boost::any&)>, type_info_hash, equal_ref>::iterator it = fs.find(boost::ref(x.type()));
        if (it != fs.end()) {
            it->second(x);
            return true;
        } else {
            return false;
        }
    }
};

struct abc {};

void fa(int i) { std::cout << "fa(" << i << ")" << std::endl; }
void fb(abc) { std::cout << "fb(abc())" << std::endl; }

int main() {
    any_visitor f;
    f.insert_visitor<int>(fa);
    f.insert_visitor<abc>(fb);

    std::vector<boost::any> xs;
    xs.push_back(1);
    xs.push_back(abc());
    xs.push_back(1.5);

    for (auto it=xs.begin(); it!=xs.end(); ++it)
        if (!f(*it)) std::cout << "no visitor registered" << std::endl;
}

打印输出:

fa(1)
fb(abc())
no visitor registered
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

boost::any 的访问者模式 的相关文章

随机推荐

  • SQL Server 2005 - 将列设置为只读

    我在 SQL Server 2005 数据库的表中有一个 InsertTime 字段 当记录首次插入数据库时 该字段默认为 getDate 我想确保此专栏不再更新 是否可以将此列设置为只读 或者是否有更好的方法来执行此操作 而无需为开发人员
  • 使用 Java 的 Google 数据存储模拟器(不使用 GAE)

    我正在使用 Google Cloud 的 Java 数据存储客户端库来访问 Cloud Datastore Note 我没有使用 App Engine 来部署我的应用程序 只是出于开发目的运行本地应用程序 按照示例 我可以读取 写入云数据存
  • 将模板成员函数的专门化定义(没有默认主体)放在源文件中是否安全?

    这就是我的意思 test h class cls public template lt typename T gt void f T t test cpp template lt gt void cls f const char main
  • 关于不使用 Interface Builder 进行 iPhone GUI 设计的教程?

    有谁知道有关仅使用代码而不是 Interface Builder 进行 iPhone GUI 设计的好教程吗 我是 iPhone 开发新手 我想更好地了解幕后发生的事情 查看 SDK 中的 UI 目录示例 它展示了以多种方式使用的所有单独控
  • 我可以在不安装的情况下使用git吗?

    我听说过有关 git 的好消息 我想在安装它之前尝试一下 如果我想在学校使用 git 那么将它放在闪存驱动器上也很棒 是否可以使用完整路径 例如 path to git init 我主要使用 Mac OS X 所以问题主要针对 Mac 但我
  • Symfony/Doctrine:DateTime 作为主键

    我正在尝试使用日期作为主键创建一个实体 问题是 Symfony 无法将我正在使用的 DateTime 转换为字符串以将其引入到 IdentityMap 中 在实体持久化期间出现以下错误 Catchable Fatal Error Objec
  • PHP 运算符优先级和字符串连接?

    请看下面的代码片段 i 1 echo i i 很快 我以为结果会是12但实际结果是21 also echo i i 我以为会是12但它的11 echo i i result is 1 echo i i 1 result is 2 But w
  • 在通用 lambda 中使用模板参数

    GCC允许使用以下语法作为扩展 a functional object that will add two like type objects auto add
  • 默认参数和可变参数函数

    有没有办法在可变参数函数中指定默认参数 也适用于模板 在 C 中 您可以将可变参数函数替换为基于命名参数习惯用法的函数 请参阅 C 常见问题解答项10 20 什么是 命名参数习惯用法 这为您提供了默认功能和方便的符号 干杯
  • 将 web.xml 安全约束与 Spring Boot 结合使用

    我有一个特殊的情况 我需要使用应用程序服务器 Weblogic 安全上下文进行身份验证 但使用 Spring Security 进行授权 我在用Spring Boot创建我的应用程序 如何添加如下所示的安全约束 通常包含在web xml
  • Python 列表:列表中具有重复值的 heapq.nlargest 索引

    假设我有一个数字列表 my list 3 8 4 2 8 1 1 2 5 1 我现在想找到这个列表中两个最大数字的索引 所以 我尝试 import heapq max vals heapq nlargest 2 my list index1
  • 在 Python 中连接字符串的首选方法是什么? [复制]

    这个问题在这里已经有答案了 自从Python的string无法更改 我想知道如何更有效地连接字符串 我可以这样写 s stringfromelsewhere 或者像这样 s s append somestring later s join
  • 为什么要在打印之前读取输入?

    I m having some problems with some basic I O stuff Specifically the text Please enter your name is written to the output
  • Java Swing 中的 PropertyGrid

    Java Swing 是否有类似于 NET 中 PropertyGrid 的控件 如果有 是哪一个 或者至少哪一个最接近它 Thanks 没有用于此目的的内置组件 但有几个第三方项目 尤其 Java Bean 检查器 GPL 看起来很有前途
  • 具有 MaterialComponents 主题的 ActionBar 背景

    我想自定义我的 ActionBar 我的主题如下所示 在值文件夹中
  • SQLAlchemy ORM:“AttributeError:无法在行中找到列”

    我现在正在学习 SQLAlchemy 但遇到了一个令我困惑的错误 是的 这里已经有类似的问题了 但似乎没有一个得到解决 我的目标是使用ORM模式来查询数据库 所以我创建了一个模型 from sqlalchemy import Column
  • Android SecurityException:管理员不拥有该配置文件

    我有一个设备管理器应用程序 我正在尝试使用自 API 21 以来可用的 DevicePolicyManager 类的 setScreenCaptureDisabled 函数 DevicePolicyManager pManager andr
  • 在 Eclipse 中使用和测试 Web 服务

    您能告诉我们如何在 Eclipse 中测试和使用 Web 服务的最佳方法吗 我对 Web 服务的经验很少 也就是说 我使用了一个生成客户端存根的 Apache Axis 插件 我现在不需要编写自己的 Web 服务 只需使用现有的 我有 Ec
  • 计算围绕多点线的多边形

    我正在尝试计算围绕连接多个点的线 例如 GPX 轨道 的多边形 下图显示了一个示例 其中轨道为红线 所需的多边形为蓝色 为了简化 红点由 x 和 y 表示 而不是纬度 经度 如果我只有指定路径的三个点的列表 如何计算这样的环境 浅蓝色多边形
  • boost::any 的访问者模式

    我找到了这个https gist github com 2945472但我需要一个不依赖于 c 11 的实现 我尝试将其转换为仅使用升压 但遇到了一些麻烦 这是我想出的 include