3

我想对类型 map 有价值,从我看到的 boost fusion 使用 map 使用 pair ,其中 type 始终是第一个成员(所以它是 map 中的关键)?

map_type m(
    fusion::make_pair<int>('X')
  , fusion::make_pair<double>("Men"));

是否可以将值(例如上面示例中的“X”)作为键和类型值?如果不能,我至少可以根据值进行过滤(这很慢,所以很高兴知道我是否可以根据第二个参数对融合向量进行排序并在其上使用 binary_search(再次使用查看值而不是键的自定义比较器) .

4

2 回答 2

1

也许不是 in boost::fusion,而是您获取运行时值列表并根据存在的匹配项调用具有类型的仿函数的技巧。我称之为魔法开关。

您需要在编译时枚举类型,然后将运行时类型与偏移量关联到所述列表中。tuple已经为您将索引映射到类型。

您不能返回类型,但可以使用该类型调用传入的模板函数。

然而,在走这条路之前,你应该有一个具体的目标,看看是否;解决它的方法不那么复杂。

于 2013-06-30T16:05:00.517 回答
1

有趣的问题。通常这不会起作用,因为实际上没有办法在运行时用编译时已知的相同语义来表示类型,例如没有虚拟构造函数(查看现代 C++ 设计第 200 页,第 8.2 段)。但是 fusion 支持在编译时对序列for_each进行迭代并调用运行时函数对象。现在这个函数对象可以是一个通用过滤器,如果它的通用谓词返回 true,则将调用转发到另一个通用函数对象。

现在她是代码:

#include <boost/fusion/container/map.hpp>
#include <boost/fusion/algorithm/iteration/for_each.hpp>

#include <string>
#include <iostream>
#include <typeinfo>

using namespace boost::fusion;


template<class Pred,class Fun>
 struct filter {
    Pred pred_;
    Fun& fun_;

    filter(Pred p, Fun& f)
        : pred_(p)
        , fun_(f)
    {}

    template<class Pair>
    void operator()(Pair& pair) const {
        if (pred_(pair.second))
            fun_(pair);
    }
 };

 template<class Pred,class Fun>
 filter<Pred,Fun> make_filter(Pred p, Fun& f) {
    return filter<Pred,Fun>(p, f);
 }

 typedef map 
    < pair<int, char>
    , pair<double, std::string>
 > map_type;

 struct fun {
    template<class First,class Second>
    void operator()(pair<First,Second>& t) const {
        std::cout 
            << typeid(First).name() << std::endl
            << typeid(Second).name() << ":" << t.second << std::endl;
    }
 };

 struct mypred {
    template<class T>
    bool operator()(T const&) const {
        return false;
    }

    bool operator()(char c) const {
        return c=='X';
    }
};

int main(int argc, char** argv) {

    map_type m(
        make_pair<int>('X'), 
        make_pair<double>("Men")
    );

    for_each(m, make_filter(mypred(),fun()));

    return 0;
}

过滤器类存储一个谓词和一个函数对象。如果谓词pair.second在您的情况下返回 true,'X'它会调用函数对象。make_filter是创建过滤器的小帮手。现在剩下两段 lof 代码:我的非常特殊的 predicate mypred,它只接受char(你必须处理更一般的实现的重载)和我的函数对象fun,它输出类型信息和值。在 mainfor_each中使用filter. 请注意:过滤器旨在通过引用获取函数对象,因此它可以传输参数和结果。最后,这是临时访问的一种变体. 如果您关心速度,您应该知道几乎所有内容都可以内联。在此特定示例中,仅比较字符,对于所有其他类型,结果是false并且不调用任何函数。当然还有很大的改进空间,但我现在没有时间去做。可能有更好的方法来实现这一点,但这是我使用 boost.fusion 的第一个程序:-)。

于 2013-07-12T14:48:36.990 回答