我如何构造一个填充有一些统一值的std :: array? [英] How can I construct an std::array filled with some uniform value?

查看:97
本文介绍了我如何构造一个填充有一些统一值的std :: array?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

std :: array (在编译时使用较新的C ++版本),例如

std::array can be constructed (at compile time with newer C++ versions) with specific values, e.g.

std::array a{1, 4, 9};

但是-它没有构造函数,也没有标准库命名的构造函数惯用语,只取一个值并将其复制。也就是说,我们没有:

however - it does not have a constructor, or a standard-library named constructor idiom, taking a single value and replicating it. i.e. we don't have:

std::array<int, 3> a{11};
// a == std::array<int, 3>{11, 11, 11};

因此,我们如何构造仅给出要重复的值的数组?

How can we, therefore, construct an array given just the value to repeat?

编辑:我正在寻找一种解决方案,该解决方案甚至适用于无法默认构造的元素类型;因此,我不需要的是通过默认构造数组然后填充它的解决方案-尽管事实对于 int

I'm looking for a solution which would work even for element types which are not default constructible; so, a solution going through default-constructing the array, then filling it, is not what I'm after - despite the fact that this will work for the case of int (like in the example).

推荐答案

我们可以编写适当的命名构造函数惯用法以实现此目的

We can write an appropriate named constructor idiom to achieve this

实现有点笨拙,但是,因为我们需要使用索引技巧 ,它在C ++ 11中需要很多样板,所以我们假设C + +14:

The implementation is a bit clunky, however, as we need to use the "indices trick" that takes a lot of boilerplate in C++11, so let's assume C++14:

namespace detail {

template<size_t, class T>
constexpr T&& identity(T&& x) { return std::forward<T>(x); }

template<class T, size_t... Indices>
constexpr auto array_repeat_impl(T&& x, std::index_sequence<Indices...>)
{
    return std::experimental::make_array(identity<Indices>(x)...);
}

} // end detail

template<size_t N, class T>
constexpr auto array_repeat(T&& x)
{
    return detail::array_repeat_impl(std::forward<T>(x), std::make_index_sequence<N>());
}

请参见 GodBolt

如果可以编译代码C ++ 20,则可以删除对 make_array 并写:

If you can compile your code C++20, you can drop the dependency on make_array and write:

namespace detail {

template<size_t, class T>
constexpr T&& identity(T&& x) { return std::forward<T>(x); }

template<class T, size_t... Indices>
constexpr auto array_repeat_impl(T&& x, std::index_sequence<Indices...>)
{
    return std::array{identity<Indices>(x)...};
}

} // end detail

template<size_t N, class T>
constexpr auto array_repeat(T&& x)
{
    return detail::array_repeat_impl(std::forward<T>(x), std::make_index_sequence<N>());
}

GodBolt

注意:

  • This solution is somewhat similar to Jared Hoberock's tuple_repeat, part of his tuple utilities for C++11.
  • Thanks goes to @Caleth and @L.F. for pointing out a inappropriate forwarding in array_repeat_impl.

这篇关于我如何构造一个填充有一些统一值的std :: array?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆