是否可以在运行时迭代mpl :: vector而无需实例化向量中的类型?

Mar*_*cin 18 c++ foreach boost vector boost-mpl

通常,我会使用boost::mpl::for_each<>()遍历a boost::mpl::vector,但这需要一个带有模板函数的仿函数,如下所示:

template<typename T> void operator()(T&){T::staticCall();}

我的这个问题是我不希望的物体T被实例化也for_each<>.我根本不需要T参数operator().有没有办法实现这一点,或者替代方法for_each<>是不将类型为T的对象传递给模板函数?

最理想的是,我希望operator()定义如下所示:

template<typename T> void operator()(){T::staticCall();}

当然,我不希望在通话之前对T进行实例化.任何其他提示/建议也欢迎.

con*_*ius 14

刚遇到同样的情况,并为我想分享的问题提供了不同的解决方案.它不是那么明显,但它使用现有的算法.这个想法是使用指针代替.

typedef boost::mpl::vector<type1*, type2*> container;

struct functor
{
    template<typename T> void operator()(T*)
    {
        std::cout << "created " << typeid(T).name() << std::endl;
    }
};

int main()
{
    boost::mpl::for_each<container>(functor());
}
Run Code Online (Sandbox Code Playgroud)

所以这里我们得到一个空指针,但我们不在乎,因为我们不会使用它们.

正如我之前所说,代码中并不明显,可能需要一些额外的注释,但它仍然可以在不编写任何其他代码的情况下解决问题.

添加

我认为Diego Sevilla提出了类似的建议.

  • 这很聪明.您可以使用`mpl :: transform`来动态定义"指针"版本:`boost :: mpl :: for_each <boost :: mpl :: transform <MyTypes,boost :: add_pointer <boost :: mpl :: _1 >> :: type>(Functor());` (4认同)
  • @ kizzx2您甚至可以不提供指针,而是包含该类型的空类型. (4认同)

Luc*_*lle 13

有趣的问题!据我所知,Boost.MPL似乎没有提供这样的算法.但是,使用迭代器编写自己的应该不会太困难.

这是一个可能的解决方案:

#include <boost/mpl/begin_end.hpp>
#include <boost/mpl/next_prior.hpp>
#include <boost/mpl/vector.hpp>

using namespace boost::mpl;


namespace detail {

template < typename Begin, typename End, typename F >
struct static_for_each
{
    static void call( )
    {
        typedef typename Begin::type currentType;

        F::template call< currentType >();
        static_for_each< typename next< Begin >::type, End, F >::call();
    }
};


template < typename End, typename F >
struct static_for_each< End, End, F >
{
    static void call( )
    {
    }
};

} // namespace detail


template < typename Sequence, typename F >
void static_for_each( )
{
    typedef typename begin< Sequence >::type begin;
    typedef typename end< Sequence >::type   end;

    detail::static_for_each< begin, end, F >::call();
}
Run Code Online (Sandbox Code Playgroud)

[命名可能不是很好,但很好......]

以下是使用此算法的方法:

struct Foo
{
    static void staticMemberFunction( )
    {
        std::cout << "Foo";
    }
};


struct Bar
{
    static void staticMemberFunction( )
    {
        std::cout << "Bar";
    }
};


struct CallStaticMemberFunction
{
    template < typename T >
    static void call()
    {
        T::staticMemberFunction();
    }
};


int main()
{
    typedef vector< Foo, Bar > sequence;

    static_for_each< sequence, CallStaticMemberFunction >(); // prints "FooBar"
}
Run Code Online (Sandbox Code Playgroud)