使用C++ 11 std::array,我是否可以保证语法std::array<T, N> x;将默认初始化数组的所有元素?
编辑:如果没有,是否有一个语法可以在所有数组(包括零大小的数组)上工作,以将所有元素初始化为默认值?
编辑:在cppreference上,默认的构造函数描述说:
(constructor) (implicitly declared) (public member function)
default-constructs or copy-constructs every element of the array
Run Code Online (Sandbox Code Playgroud)
所以答案可能是肯定的.但我想根据标准或未来标准确定这一点.
在C++ 11中,我将如何编写一个采用已知类型但未知大小的std ::数组的函数(或方法)?
// made up example
void mulArray(std::array<int, ?>& arr, const int multiplier) {
for(auto& e : arr) {
e *= multiplier;
}
}
// lets imagine these being full of numbers
std::array<int, 17> arr1;
std::array<int, 6> arr2;
std::array<int, 95> arr3;
mulArray(arr1, 3);
mulArray(arr2, 5);
mulArray(arr3, 2);
Run Code Online (Sandbox Code Playgroud)
在我的搜索过程中,我只找到了使用模板的建议,但这些看起来很混乱(标题中的方法定义),而且我想要完成的内容过多.
是否有一种简单的方法可以实现这一点,就像普通的C风格数组一样?
是没有
std::array<T,size>::array(const T& value);
Run Code Online (Sandbox Code Playgroud)
疏忽?它似乎对我有用,而动态容器(如std::vector)确实有类似的构造函数.
我完全清楚
std::array<T,size>::fill(const T& value);
Run Code Online (Sandbox Code Playgroud)
但这不是构造函数,内存将首先归零.如果我想什么都-1好像这个家伙?
如果我想构建一个非常简单的数组
int myArray[3] = {1,2,3};
Run Code Online (Sandbox Code Playgroud)
我应该用std::array吗?
std::array<int, 3> a = {{1, 2, 3}};
Run Code Online (Sandbox Code Playgroud)
使用std :: array比使用常规的有什么好处?性能更高吗?更容易处理复制/访问?
鉴于此结构:
struct Foo {
std::array<int, 8> bar;
};
Run Code Online (Sandbox Code Playgroud)
bar如果我没有实例,如何获取数组元素的数量Foo?
任何人都可以解释一下记忆的布局
std::vector<std::array<int, 5>> vec(2)
Run Code Online (Sandbox Code Playgroud)
它是否提供具有2行5个元素的2D数组的连续内存块?
据我所知,矢量矢量
std::vector<std::vector<int>> vec(2, std::vector<int>(5))
Run Code Online (Sandbox Code Playgroud)
提供存储器中不同位置的两个 长度为 5个元素的连续数组的存储器布局.
对于数组的向量是否相同?
我即将将大量旧的 C++ 代码转换为更现代的 C++。
该代码中有许多原始的二维数组,例如:
Foo bar[XSIZE][YSIZE];
Run Code Online (Sandbox Code Playgroud)
我即将用以下内容替换这些声明
std::array<std::array<Foo, YSIZE>, XSIZE> bar;
Run Code Online (Sandbox Code Playgroud)
这是一种方便的方法,因为语句保持不变,并且代码的行为应该与原始数组相同,并且具有能够在调试版本中进行越界检查的额外好处。
但在我看来,这std::array<std::array<Foo, YSIZE>>有点麻烦而且不容易阅读,而且如果使用 3D 数组(虽然我没有),情况会更糟。
现在我正在使用这个宏来使声明更具可读性:
#define DECLARE_2D_ARRAY(type, x, y) std::array<std::array<type, y>, x>
...
DECLARE_2D_ARRAY(Foo, XSIZE, YSIZE) bar;
Run Code Online (Sandbox Code Playgroud)
但我觉得这是一个宏黑客,我想知道是否有一种更干净、更 C++ 的方法来做类似的事情。
考虑以下代码片段,这是C++ 11编译器完全可以接受的:
#include <array>
#include <iostream>
auto main() -> int {
std::array<double, 0> A;
for(auto i : A) std::cout << i << std::endl;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
根据标准§23.3.2.8[ 零大小的阵列 ]:
1数组应为特殊情况提供支持N == 0.
2在这种情况下N == 0,begin() == end() ==独特的价值.返回值
data()未指定.
3调用front()或back()零大小数组的效果是未定义的.
4成员函数swap()应具有等效的noexcept-speci fi cationnoexcept(true).
如上所示,零大小的std::arrays在C++ 11中是完全允许的,与零大小的数组(例如int A[0];)相比,它们被明确禁止,但是一些编译器(例如,GCC)允许它们以未定义的行为为代价. .
考虑到这种"矛盾",我有以下问题:
为什么C++委员会决定允许零大小的std::arrays?
有什么有价值的用途吗?
我怎样才能a3编译?
int main()
{
int a1[] = { 1, 2, 3 };
std::array<int, 3> a2 = { 1, 2, 3 };
std::array<int> a3 = { 1, 2, 3 };
}
Run Code Online (Sandbox Code Playgroud)
使用初始化列表时,对数组的大小进行硬编码是非常不方便的,也是很脆弱的,特别是长的列表.有什么工作吗?我希望如此,否则我很失望,因为我讨厌C阵列,std::array应该是他们的替代品.
考虑:
static constexpr unsigned num_points{ 7810 };
std::array< double, num_points > axis;
for (int i = 0; i < num_points; ++i)
{
axis[i] = 180 + 0.1 * i;
}
Run Code Online (Sandbox Code Playgroud)
axis是全类常量。我想避免像其他任何全局变量一样初始化它。可以在编译时完成吗?
这是完整的最后一堂课:
// https://www.nist.gov/pml/atomic-spectroscopy-compendium-basic-ideas-notation-data-and-formulas/atomic-spectroscopy
// https://www.nist.gov/pml/atomic-spectra-database
struct Spectrum
{
static constexpr unsigned _num_points{ 7810 };
using Axis = std::array< double, _num_points >;
static constexpr Axis _x{ [] () // wavelength, nm
{
Axis a {};
for( unsigned i = 0; i < _num_points; ++i )
{
a[ i ] …Run Code Online (Sandbox Code Playgroud)