使用常量值初始化 std::array
Initializing a std::array with a constant value
我需要用常量值初始化std::array
的所有元素,就像可以用std::vector
一样
#include <vector>
#include <array>
int main()
{
std::vector<int> v(10, 7); // OK
std::array<int, 10> a(7); // does not compile, pretty frustrating
}
有没有办法优雅地做到这一点?
现在我正在使用这个:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
但我想避免使用显式代码进行初始化。
使用std::index_sequence
,您可以执行以下操作:
namespace detail
{
template <typename T, std::size_t ... Is>
constexpr std::array<T, sizeof...(Is)>
create_array(T value, std::index_sequence<Is...>)
{
// cast Is to void to remove the warning: unused value
return {{(static_cast<void>(Is), value)...}};
}
}
template <std::size_t N, typename T>
constexpr std::array<T, N> create_array(const T& value)
{
return detail::create_array(value, std::make_index_sequence<N>());
}
随着使用情况
auto a = create_array<10 /*, int*/>(7); // auto is std::array<int, 10>
与std::fill
解决方案相反,它处理非默认的可构造类型。
唉不是;std::array
支持聚合初始化,但这还不够。
幸运的是,您可以使用std::fill
,甚至std::array<T,N>::fill
,从 C++20 开始,随着后者变得constexpr
,它很优雅
。参考: https://en.cppreference.com/w/cpp/container/array/fill
你可以执行以下操作
std::array<int, 10> a;
a.fill(2/*or any other value*/);
或者使用算法头文件中的std::fill
。 包含算法头文件使用
#include <algorithm>
从 C++17 开始,您可以编写一个 constexpr 函数来有效地设置数组,因为元素访问器现在是 constexpr。此方法也适用于设置初始值的各种其他方案:
#include <array>
template<typename T, size_t N>
constexpr auto make_array(T value) -> std::array<T, N>
{
std::array<T, N> a{};
for (auto& x : a)
x = value;
return a;
}
int main()
{
auto arr = make_array<int, 10>(7);
}
如前所述,fill
解决方案不适用于非默认的可构造类型。index_sequence
解决方案是正确的,但有点冗长。
给定一个值t
(任何类型(和一个编译常量N
,下面计算出一行中所需的解决方案。
std::apply([&](auto... dummy) {return std::array{(dummy, t)...};}, std::array<int, N>{});
在此处查看完整代码:https://godbolt.org/z/jcq4fqMsE
此解决方案可以应用于 C++17,并对早期版本进行一些修改。
std::array
类型是支持列表初始化的聚合:
std::array<int, 10> a{2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
它还支持聚合初始化:
std::array<int, 10> a = {2, 2, 2, 2, 2, 2, 2, 2, 2, 2};
这对于长数组来说既不方便又容易出错,您最好使用像 Jarod42 这样的解决方案。
这可以通过创建一个返回所需数组的函数模板来相当容易地完成,如下所示。甚至可以在编译时初始化数组!(请参阅答案末尾给出的 C++17 示例演示(。
template<std::size_t N> std::array<int, N> make_array(int val)
{
std::array<int, N> tempArray{}; //create local array
for(int &elem:tempArray) //populate it
{
elem = val;
}
return tempArray; //return it
}
int main()
{
//---------------------V-------->number of elements
auto arr = make_array<10>(7);
//------------------------^---->value of element to be initialized with
//lets confirm if all objects have the expected value
for(const auto &elem: arr)
{
std::cout << elem << std::endl; //prints all 7
}
}
演示
另请注意,甚至可以在编译时使用 C++17 执行此操作。演示 C++17
从C++20开始,ranges
fill
std::array<int, 10> a2;
std::ranges::fill(a2, 10);
此外,如果数组很小(对于较大的数组,它可能看起来很奇怪(,则从C++17(参数推导(
auto a = std::array{2,2,2,2};
- C++11 中不同类型的对象的 std::array 的替代方案
- constexpr begin of a std::array
- C++如果必须在编译时确定大小,std::array 有什么意义?
- 标准::unordered_map 中的 std::array 的值初始化
- 确保编译时的特定 std::array 位置
- std::array的长度有大小限制吗?
- 将 std::array 移动到另一个 std::array
- 检查输入 std::array 指针数据是否等于某个常量数组
- 如何读/写或遍历 std::array 中的特定元素范围?
- 是否可以使用 std::array 作为 POD 结构的数据容器?
- 如何在C++中传递一个大小未知的 std::array?
- 将 std::array 推回 std::vector N 次的优雅方式
- 如何在 c++11 中静态断言 std::array 类成员进行排序?
- unqualified sort() -- 为什么它在 std::vector 上使用而不是在 std::array 上
- 按值返回 std::array
- 如何将变量内容常量转换为 std::array 的大小?
- 将初始化器列表/聚合初始化转发到 std::array 成员
- 无法推断类中的类型,构造函数采用 std::array
- 为什么 char 可以在 std::array 中初始化为 nullptr,而不是单独初始化?
- C++ IDE 不会推断/自动完成对模板类中的 std::array 下标表达式的成员访问