我如何构造一个填充有一些统一值的std :: array? [英] How can I construct an std::array filled with some uniform value?
问题描述
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>());
}
注意:
- 此解决方案是有点类似于Jared Hoberock的
tuple_repeat
,它是 tuple实用程序的一部分for C ++ 11 。 - 感谢@Caleth和@LF指出
array_repeat_impl
中不适当的转发。
- 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屋!