运行时在boost :: mpl :: vector中找到第一个匹配项

时间:2015-03-27 15:46:20

标签: c++ boost boost-mpl c++98 boost-fusion

我有一个boost::mpl::vector,现在需要一个模板(函数),其中"迭代"在找到第一个匹配(在运行时)之前的类型。类似于boost::fusion::find_if的东西,但没有 sequence 是运行时值。

将它想象成这样:

typedef boost::mpl::vector<Foo, Bar> Types;

template< typename T >
struct Finder {
  bool operator()() const;
};

struct Callback {
  template< typename T >
  void operator()();
};

Callback callback;

magic_find_if<Types, Finder>(callback);

在mpl / fusion中找不到这样的东西(找不到它)


我知道,Callback::operator()的所有变体都将被&#34;实例化&#34;但这没关系。可以想象用Variadic模板来实现它,但遗憾的是我坚持使用C ++ 98。

1 个答案:

答案 0 :(得分:1)

我建议将过滤器和回调组合成一个条件操作:

template <template<typename> class Finder, typename Callback>
struct ConditionOperation {
    ConditionOperation(Callback cb = {}) : _callback(std::move(cb)) 
    { }

    template <typename T>
    void operator()(boost::type<T>) const {
        if (Finder<T>()())
            _callback.template operator()<T>();
    }

private:
    Callback _callback;
};

然后,在EricNiebler答案之后,你可以自由地写下:

ConditionOperation<Finder, Callback> op;
mpl::for_each<Types, boost::type<mpl::_1> >(op);

这是一个完整的演示

<强> Live On Coliru

#include <boost/type.hpp>
#include <boost/mpl/vector.hpp>
#include <boost/mpl/for_each.hpp>
#include <iostream>

struct Foo { enum { id = 879 }; };
struct Bar { enum { id = 321 }; };
struct Qux { enum { id = 555 }; };
typedef boost::mpl::vector<Foo, Bar, Qux> Types;

template <typename T>
struct Finder {
  bool operator()() const { return T::id > 500; }
};

struct Callback {
    template<typename T> void operator()() const {
        std::cout << __PRETTY_FUNCTION__ << "\n";
    }
};

template <template<typename> class Finder, typename Callback>
struct ConditionOperation {
    ConditionOperation(Callback cb = {}) : _callback(std::move(cb)) 
    { }

    template <typename T>
    void operator()(boost::type<T>) const {
        if (Finder<T>()())
            _callback.template operator()<T>();
    }

private:
    Callback _callback;
};

int main() {
    using namespace boost;

    ConditionOperation<Finder, Callback> op;
    mpl::for_each<Types, boost::type<mpl::_1> >(op);
}

打印

void Callback::operator()() const [with T = Foo]
void Callback::operator()() const [with T = Qux]

¹boost::mpl::for_each without instantiating