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

我想用 mpl::vector_c 中的“包含”值初始化 boost::array 内容。此初始化应在编译时执行。我在 SO 上看到了一些使用预处理器的解决方案,但我不知道如何将它们应用于可变参数模板案例。

请注意,在上面的示例代码中,mpl::vector_c 的元素与 Test 的模板参数相同。在实际代码中并非如此,而是values_type具有长度 == 模板参数的数量,但实际值来自于 mpl 算法序列的应用。因此,不要假设论点是相同的。

希望问题清楚,谢谢!

4

1 回答 1

8

一种方法是使用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.


相同的技术通常用于将 a 扩展std::tuple为 a std::array将 std::tuple 转换为 std::array C++11)、函数调用(“解包”元组以调用匹配的函数指针)等。

于 2012-05-31T10:00:50.683 回答