5

C++11で私は次のようなものを持っています

#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/size.hpp>

#include <boost/array.hpp>

#include <iostream>

namespace mpl = boost::mpl;

template<std::size_t ... Args>
struct Test
{
            typedef mpl::vector_c<std::size_t, Args ...> values_type;

            static const boost::array<std::size_t, sizeof...(Args)> values;
};


int main (int argc, char** argv)
{
            Test<3,2,5,6,7> test;
            return 0;
}

boost::arrayの内容をmpl::vector_cの「contained」の値で初期化したいと思います。この初期化は、コンパイル時に実行する必要があります。プリプロセッサを使用したいくつかのソリューションをSOで見ましたが、それらを可変個引数テンプレートの場合に適用する方法がわかりません。

上記のサンプルコードでは、mpl::vector_cの要素がTestのテンプレートパラメータと同じであることに注意してください。実際のコードではそうではなく、代わりvalues_typeに長さ==テンプレート引数の数がありますが、実際の値は一連のmplアルゴリズムの適用から生じます。したがって、引数が同じであると想定しないでください。

質問が明確であることを願っています、ありがとう!

4

1 に答える 1

8

1つの方法はat_c、vector_cをパラメーターパックに抽出し、それを展開して配列を初期化するために使用することです。

#include <cstdio>
#include <array>
#include <boost/mpl/vector_c.hpp>
#include <boost/mpl/at.hpp>
#include <boost/mpl/size.hpp>
#include <utils/vtmp.hpp>
// ^ https://github.com/kennytm/utils/blob/master/vtmp.hpp

template <typename MPLVectorType>
class to_std_array
{
    typedef typename MPLVectorType::value_type element_type;
    static constexpr size_t length = boost::mpl::size<MPLVectorType>::value;
    typedef std::array<element_type, length> array_type;

    template <size_t... indices>
    static constexpr array_type
            make(const utils::vtmp::integers<indices...>&) noexcept
    {
        return array_type{{
            boost::mpl::at_c<MPLVectorType, indices>::type::value...
        }};
    }

public:
    static constexpr array_type make() noexcept
    {
        return make(utils::vtmp::iota<length>{});
    }
};

int main()
{
    typedef boost::mpl::vector_c<size_t, 3, 2, 5, 6, 7> values;

    for (size_t s : to_std_array<values>::make())
        printf("%zu\n", s);
    return 0;
}

ここで使用しstd::arrayていますが、に変更するだけでboost::array機能します。表現

to_std_array<MPLVector>::make()

make()関数がであるため、コンパイル時に実行されますconstexpr


同じ手法は、通常、std::tupleaをstd::arraystd::tupleをstd::array C ++ 11に変換)、関数呼び出し(タプルを「アンパック」して、一致する関数ポインターを呼び出す)などに展開する場合に使用されます。

于 2012-05-31T10:00:50.683 に答える