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

Runtime find first match in boost::mpl::vector

本文关键字:第一个 查找 vector boost mpl 运行时      更新时间:2023-10-16

我有一个boost::mpl::vector,现在需要一个模板(函数),它在类型上"迭代",直到找到第一个匹配(在运行时)。类似于boost::fusion::find_if的东西,但没有序列作为运行时值。

会把它想象成这样工作吗:

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()的所有变体都会被"实例化",但这没关系。可以想象用Variadic Templates实现这一点,但遗憾的是,我一直使用C++98。

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

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;
};

然后,在Eric Niebler的回答后,你可以自由地写下:

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

这是一个完整的演示

在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]

cco boost::mpl::for_each而不实例化