是否可以反向使用boost fusion map,又名是567,值是类型?

时间:2013-06-30 15:12:21

标签: c++ boost visitor-pattern boost-fusion

我想拥有 键入map的值,从我看到的boost fusion使用的是使用pair的map,其中type始终是第一个memeber(所以它是地图中的键)?

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

是否可以创造价值(例如&#39; X&#39;在上面的例子中)键和类型值? 如果没有,我至少可以根据值进行过滤(这很慢,所以很高兴知道我是否可以基于第二个参数对融合向量进行排序并对其使用binary_search(同样使用自定义比较器查看值,而不是键) 。

2 个答案:

答案 0 :(得分:1)

也许不在boost::fusion中,但是你可以获取运行时值列表并根据存在的匹配类型调用类型的仿函数。我称之为魔术开关。

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

您不能返回类型,而是可以使用该类型调用传入的模板functo。

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

答案 1 :(得分:1)

有趣的问题。 Normaly这不起作用,因为在运行时没有真正的方法来表示编译时已知的相同语义,例如没有虚拟构造函数(参见Moder C ++ Design第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代码:我的特殊谓词mypred,它只接受char(你必须处理重载以获得更多通用实现)和我的函数对象fun输出类型信息和价值。在主for_each中使用filter进行调用。请注意:过滤器旨在通过引用获取函数对象,以便它可以传输参数和结果。最后,这是ad hoc visitation的变体。如果您关心速度,您应该知道所有内容都可以内联。在此特定示例中,仅比较字符,对于所有其他类型,结果为false并且不调用任何函数。当然还有很大的改进空间,但我现在没有时间去做。可能有更好的方法来实现这个,但这是我的第一个使用boost.fusion的程序:-)。