C++ 11在constexpr函数中初始化具有统一值的数组

mar*_*ack 6 c++ constexpr c++11

我有一个类模板,它基于模板参数构建一个简单的数组作为其成员之一.我需要能够将数组中的每个元素初始化为其中一个构造函数中的单个值.不幸的是这个构造函数必须是constexpr.

相关部分归结为:

template <typename T, size_t N>
class foo
{
  T data[N];

  constexpr foo(T val)
  {
    // initialize data with N copies of val
  }
};
Run Code Online (Sandbox Code Playgroud)

使用std::fill或循环与constexpr要求不兼容.初始化: data{val}仅设置数组的第一个元素,并对剩余部分进行零初始化.

怎么能实现这一目标?

我觉得应该有一个可变参数模板和元组等的解决方案......

oak*_*kad 8

奇怪的是,c ++ 14中存在一个问题的解决方案(使用-std=c++1yon gcc 编译示例;另请参阅Praetorian的更详细的c ++ 11解决方案的注释):

template <size_t N>
struct bar {
    template <typename T, typename ...Tn>
    static constexpr auto apply(T v, Tn ...vs)
    {
        return bar<N - 1>::apply(v, v, vs...);
    }
};

template <>
struct bar<1> {
    template <typename T, typename ...Tn>
    static constexpr auto apply(T v, Tn ...vs)
    {
        return std::array<T, sizeof...(vs) + 1>{v, vs...};
    }

};

template <typename T, size_t N>
struct foo {
    std::array<T, N> data;

    constexpr foo(T val)
    : data(bar<N>::apply(val))
    {}
};
Run Code Online (Sandbox Code Playgroud)

(我用std :: array替换了POD数组 - 假设它不会对你的用例造成任何问题).

现场示例如下:http://coliru.stacked-crooked.com/a/4731a10ee54563b9


Jar*_*d42 6

您可以使用以下内容:(https://ideone.com/xTacMP)

namespace detail
{
    template <typename T, std::size_t...Is>
    constexpr std::array<T, sizeof...(Is)> make_array(T val, index_sequence<Is...>)
    {
        return {(static_cast<void>(Is), val)...};
    }
}

template <std::size_t N, typename T>
constexpr std::array<T, N> make_array(T val)
{
    return detail::make_array(val, make_index_sequence<N>());
}
Run Code Online (Sandbox Code Playgroud)

然后叫它:

constexpr foo(T val) : data(make_array<N>(val)) {}
Run Code Online (Sandbox Code Playgroud)