BOOST_FUSION_ADAPT_STRUCT 的限制

2024-02-29

我尝试过玩BOOST_FUSION_ADAPT_STRUCT宏并尝试了一些天真的事情,例如使用 Fusion 打印任何任意结构。

从此开始文档中给出的示例代码 http://www.boost.org/doc/libs/1_55_0/libs/fusion/doc/html/fusion/adapted/adapt_struct.html,我无法在我的改编结构上执行融合序列允许的一些操作。

#include <boost/fusion/adapted.hpp>
#include <boost/fusion/sequence/io/out.hpp>
#include <boost/fusion/sequence/intrinsic.hpp>
#include <boost/fusion/view.hpp>
#include <iostream>

namespace fuz = boost::fusion;

namespace demo
{
    struct employee
    {
        std::string name;
        int age;
    };
}

// demo::employee is now a Fusion sequence
BOOST_FUSION_ADAPT_STRUCT(
    demo::employee,
    (std::string, name)
    (int, age))

int main()
{
    // tried to initialize an employee like a fusion sequence
    // but it didnt work
    // demo::employee e("bob", 42);

    demo::employee e;
    e.name = "bob";
    e.age = 42;

    // Access struct members with fusion random access functions
    // ok
    std::cout << fuz::at_c<0>(e) << std::endl; 

    // tried to print the struct like any othe fusion sequence
    // didnt work
    // std::cout << e << std::endl;

    // I made it work by using a fusion view
    // is it the right way?
    std::cout << fuz::as_nview<0, 1>(e) << std::endl;
}

这让我产生以下问题:

  • 为什么融合魔法在这里不起作用?

  • 使用视图是打印改编结构的正确方法吗?

  • 适应的结构可以在多大程度上用作融合序列?


来自boost::fusion文档:

I/O 运算符在命名空间 boost::fusion 中重载

这意味着如果您想要这些的隐式集成operator<<,你需要注入boost::fusion当前命名空间中的命名空间(::此处),或明确使用它们。

总而言之,添加:

using namespace boost::fusion;

应该适合你的情况。 或者为了明确使用,您必须编写:

boost::fusion::operator<<(std::cout, e) << std::endl;

- - 编辑 - -

看完之后boost::fusion的代码有点,看来你很困惑,因为科尼格的查找 of boost::fusion::operators::operator<<如果您的论点是真实的,则选择该选项boost::fusion::sequence.

这就是为什么你不需要注入boost::fusion命名空间,也没有显式调用boost::fusion::operator<<对于定义在boost::fusion命名空间。

一些解释:

我不会解释 Koenig 查找(也称为参数相关查找 http://en.wikipedia.org/wiki/Argument-dependent_name_lookup- ADL) 在这里,因为这不是重点,但基本上,它指出,如果您使用的变量的类型位于命名空间内,则函数查找将扩展到该参数的命名空间。

在这种特殊情况下,包括boost/fusion/sequence/io/out.hpp将定义boost::fusion::operator::operator<<然后将被注入到boost::fusion命名空间。

$ cat /usr/local/include/boost/fusion/sequence/io/out.hpp
[...]
namespace boost { namespace fusion
{
    [...]
    namespace operators
    {
        template <typename Sequence>
        inline typename
            boost::enable_if<
               fusion::traits::is_sequence<Sequence>
              , std::ostream&
            >::type // this is just a SFINAE trick to ensure
                    // the function will only be selected for
                    // actual boost::fusion::sequence
        operator<<(std::ostream& os, Sequence const& seq)
        {
            return fusion::out(os, seq); // this will print out the sequence
        }
    }
    using operators::operator<<; // here the operator<< is injected
                                 // in boost::fusion
}}

这意味着调用使用 operator<< 参数的类型在 boost::fusion 命名空间将找到适当的重载。

使用其类型不位于此命名空间中的参数的调用将无法解析正确的重载operator<<(您的示例就是这种情况)。

您可以通过在中定义您的类型来检查boost::fusion命名空间。

namespace boost { namespace fusion {
struct employee
{
  std::string name;
  int age;
};
}}

BOOST_FUSION_ADAPT_STRUCT(
    boost::fusion::employee,
    (std::string, name)
    (int, age))

[...]
boost::fusion::employee e;
std::cout << e << std::endl; // ADL will work here

旁注:如果您想调试此类名称查找问题,您应该使用gdb。这样您将始终知道选择了哪个重载。在这种情况下:

$ cat fusion.cpp
#include <iostream>
#include <cstdlib>

#include <boost/fusion/container/vector.hpp>
#include <boost/fusion/sequence/io.hpp>

int main(int, char**)
{
  boost::fusion::vector<int, char> foo(42, '?');
  std::cout << foo << std::endl;

  return EXIT_SUCCESS;
}

$ gdb -q ./fusion
Reading symbols for shared libraries ... done
(gdb) b 10
Breakpoint 1 at 0x1000012f7: file fusion.cpp, line 10.
(gdb) r
Starting program: /Users/avallee/Projects/tmp/fusion
Reading symbols for shared libraries ++............................. done

Breakpoint 1, main (unnamed_arg=0x7fff5fbffb60, unnamed_arg=0x7fff5fbffb60) at fusion.cpp:10
10    std::cout << foo << std::endl;
(gdb) s
boost::fusion::operators::operator<< <boost::fusion::vector<int, char, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_, boost::fusion::void_> > (os=@0x7fff762b5f10, seq=@0x7fff5fbffb18) at out.hpp:38
38              return fusion::out(os, seq);
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

BOOST_FUSION_ADAPT_STRUCT 的限制 的相关文章

随机推荐

  • 本地定时器对象事件处理程序

    我在类函数中有以下代码 public function foo void var timer Timer new Timer 10000 1 timer addEventListener TimerEvent TIMER COMPLETE
  • SQL从另一列插入不同值的计数

    我目前正在努力解决以下查询 我在数据库中有一个表 其中包含公司列表及其拥有的许多产品 我正在寻找Count的数量独特的产品他们拥有并将其插入到表中其公司名称所在的行中 我尝试过以下方法 INSERT INTO table name SET
  • 如何在 JavaScript 中有效地将大块细分为许多大小为 2 的幂的小块

    建设关闭这个答案 https stackoverflow com questions 66253424 how to efficiently segment a large block of predefined size into sma
  • Android 编译器上的 Delphi PATH 错误

    我刚刚在我办公室的 DELL 工作站中安装了 Delphi 10 Seattle 并且能够编译 32 位和 64 位 当我选择Android时 出现这样的错误 执行错误 命令 PATH C Program 文件 Java jdk1 7 0
  • 使用 OpenCV 2.2 实施 Sift

    有人知道 SIFT 实现示例与 OpenCV 2 2 的链接吗 问候 下面是一个最小的例子 include
  • 如何知道 Cosmos 中的 Cygnus 通知表名称?

    我正在使用 Cygnus 通过 httpfs 向 Cosmos 发送 Orion Context Broker 通知 Hive 历史记录中发送到 Cosmos 的数据存储在哪里 存储 Cygnus 数据的表的名称是什么 Cygnus 在 C
  • Flask URL Route:将所有其他 URL 路由到某个函数

    我正在使用 Flask 0 9 我有使用 Google App Engine 的经验 在 GAE 中 url 匹配模式按照它们出现的顺序进行评估 先到先得 Flask 中也是同样的情况吗 在 Flask 中 如何编写 url 匹配模式来处理
  • Android 多屏限定符定义

    我想创建一个与大量设备和屏幕兼容的布局 我一直在研究 发现最常见的屏幕分辨率是 249x320 480x800 600x1024 720x1280 以及与这些成比例的其他一些屏幕 好吧 阅读文档后我发现有两种方法可以做到这一点 到 3 2
  • 使用 J2V8 从 .js 执行函数

    我正在使用 J2V8 在 Android 上执行 JavaScript 代码 在我的 Java 代码中 我可以访问和执行单独 js 文件的 JavaScript 函数吗 如果可以的话 我该怎么做 与许多 JavaScript 环境一样 您只
  • Anorm 中的原子 MySQL 事务

    我编写了一个简单的命中计数器 它使用 Anorm 更新 MySQL 数据库表 我希望交易是原子的 我认为最好的方法是将所有 SQL 字符串连接在一起并执行一个查询 但这对于 Anorm 似乎是不可能的 相反 我将每个选择 更新和提交放在单独
  • 如何在 PyTorch 中保存模型架构?

    我知道我可以通过以下方式保存模型torch save model state dict FILE or torch save model FILE 但两者都不保存模型的架构 那么我们如何在 PyTorch 中保存模型的架构 就像创建一个 p
  • R CMD 氧气无法识别

    我刚刚尝试了 Roxygen 套餐 在 R 中 我可以运行 Roxygen Vignette 中的示例 但是在命令行中 R CMD roxygen未被识别为有效命令 当我跑步时R CMD help 我可以看到全部INSTALL check
  • 如何设置超时来中止工厂或服务内的 $http.get() ?

    我有以下方法getData url 在我的factory它使用 http get url 从 URL 获取数据 angular module az app factory WebServiceFactory function http q
  • 使用 ResumableJS 取消、中止和重试单个文件上传

    我已经成功地使用以下方法将多个文件分块上传到服务器可恢复JS http www resumablejs com 在上传过程中 用户可以看到整体上传进度和单个文件上传百分比 还可以暂停 恢复整个上传 我现在想要的是允许用户取消 中止单个文件上
  • 无法从没有窗口的视图中呈现弹出窗口

    这个错误说明什么 Popovers cannot be presented from a view which does not have a window 救了我一命的事情 if self view window nil popoverC
  • 如何读取浏览器中所有存储的 Cookie

    我只想读取浏览器中存储的所有 cookie 使用标准 Javascript API 我无法阅读它 但有没有一种方法可以读取所有 cookie 而不仅仅是通过我的网站注册的 cookie 浏览器安全会故意阻止这种情况 如果你能做到这一点 你就
  • 从代码运行测试时在 Eclipse 中显示 JUnit 视图

    当我在 Eclipse 中运行 Testclass 时 我会看到显示树结构以及测试是否成功的 JUnit 视图 如果我从代码开始测试 JUnitCore core new JUnitCore core run SimpleTests cla
  • MySQL语句选择特定列的最新条目

    我正在使用 MySQL 并且该表是使用以下架构创建的 CREATE TABLE example id INT UNSIGNED NOT NULL AUTO INCREMENT version INT UNSIGNED NOT NULL te
  • 如何加载离子段内的其他页面?

    任何人都知道如何加载离子段内的其他页面 我正在使用 ionic v4 我有三页试图在离子段内部显示 概况 疫苗接种 发育 我想将页面的功能分开以便于维护 这是孩子的详细信息页面 https i stack imgur com pta0M p
  • BOOST_FUSION_ADAPT_STRUCT 的限制

    我尝试过玩BOOST FUSION ADAPT STRUCT宏并尝试了一些天真的事情 例如使用 Fusion 打印任何任意结构 从此开始文档中给出的示例代码 http www boost org doc libs 1 55 0 libs f