我在一些地方看到std::array了在C++中使用C风格数组的建议,声称它是一种更好,更安全的替代方案,没有开销.看到:
标准容器数组[...]没有超出其容纳元素所需的空间开销,[...].换句话说,它非常像没有问题的内置阵列.(C++ 11 FAQ)
但是,据我所知,作为一个模板容器,就程序大小来说会有一个开销,因为它会为每个不同的N生成代码.
假设我的程序std::array在N的各个地方使用了几个不同的整数,这会导致代码膨胀吗?它可以忽略不计吗?
我是否应该为非类型模板参数担心这一点?
// This snippet
for (const float t : std::array{ 0.0f, 0.33f, 0.66f, 1.0f }) {
std::cout << "t = " << t << "\n";
}
// Yields the following (incorrect) values:
t = -3.91649e-28
t = 4.59037e-41
t = 2.66247e-44
t = 0
// Whereas this snippet ...
auto vals = std::array{ 0.0f, 0.33f, 0.66f, 1.0f };
for (const float t : vals) {
std::cout << "t = " << t << "\n";
}
// Yields the following (correct) values: …Run Code Online (Sandbox Code Playgroud) 在我的C++ JSON库中,我最近使用GCC7进行了回归.我删除了受影响的代码,希望了解错误.
考虑这个标题myclass.hpp:
#pragma once
template <typename X>
struct A
{
struct value_t
{
X array;
};
static A array()
{
return A();
}
friend bool operator<(const A& lhs, const A& rhs) noexcept
{
return lhs.val.array < rhs.val.array;
}
value_t val = {};
};
Run Code Online (Sandbox Code Playgroud)
如您所见,我在struct中使用名称"array"作为成员变量名称value_t,作为静态函数的名称.然后我在以下文件中包含标题:
#include <array>
using std::array; // note this!
#include "myclass.hpp"
int main()
{}
Run Code Online (Sandbox Code Playgroud)
代码用GCC6和Clang5(使用-std=c++11)编译,但GCC7报告:
In file included from example.cpp:3:0:
myclass.hpp: In function 'bool operator<(const …Run Code Online (Sandbox Code Playgroud) 根据https://en.cppreference.com/,std::vector<bool>具有类模板专业化,而std::array<bool, N>没有。不提供的原因有哪些?
c++ stdvector template-specialization class-template stdarray
struct MyClass
{
std::array<int, 10> stdArr;
MyClass() : stdArr()
{}
};
MyClass c;
Run Code Online (Sandbox Code Playgroud)
问题:
c.stdArr零初始化?我自己的矛盾答案:
它是零初始化的:
std::array希望表现得像一个c-array.如果在上面的例子中stdArr是一个c-array,它将stdArr()在初始化列表中进行零初始化.我希望member()在初始化列表中写入初始化对象.
它不是零初始化的:
std::array 通常只有一个成员,在我的情况下 int[10] _Elems;int[N]都不是默认初始化的.std::array 是一种聚合类型,暗示它是默认构造的._Elems,我认为它不是零初始化.std::array根据C++ 11标准,正确的行为是什么?
在g ++ 4.9.2和5.3.1上,此代码需要几秒钟的时间来编译并生成52,776字节的可执行文件:
#include <array>
#include <iostream>
int main()
{
constexpr std::size_t size = 4096;
struct S
{
float f;
S() : f(0.0f) {}
};
std::array<S, size> a = {}; // <-- note aggregate initialization
for (auto& e : a)
std::cerr << e.f;
return 0;
}
Run Code Online (Sandbox Code Playgroud)
增加size似乎线性增加编译时间和可执行文件大小.我无法使用clang 3.5或Visual C++ 2015重现此行为.使用-Os没有区别.
$ time g++ -O2 -std=c++11 test.cpp
real 0m4.178s
user 0m4.060s
sys 0m0.068s
Run Code Online (Sandbox Code Playgroud)
检查汇编代码显示初始化a已展开,生成4096 movl条指令:
main:
.LFB1313:
.cfi_startproc
pushq %rbx
.cfi_def_cfa_offset 16
.cfi_offset …Run Code Online (Sandbox Code Playgroud) 我需要std::array使用常量值初始化a的所有元素,就像可以使用来完成一样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
}
Run Code Online (Sandbox Code Playgroud)
有没有办法优雅地做到这一点?
现在我正在使用这个:
std::array<int, 10> a;
for (auto & v : a)
v = 7;
Run Code Online (Sandbox Code Playgroud)
但我想避免使用显式代码进行初始化。
std::array<std::pair<int, int>, 2> ids = { { 0, 1 }, { 1, 2 } };
Run Code Online (Sandbox Code Playgroud)
VS2013错误:
错误C2440:'初始化':无法从'int'转换为'std :: pair'没有构造函数可以采用源类型,或构造函数重载解析是不明确的
我究竟做错了什么?
请参阅此示例:https : //godbolt.org/z/5PqYWP
为什么这个对数组不能以与对向量相同的方式初始化?
#include <vector>
#include <array>
int main()
{
std::vector<std::pair<int,int>> v{{1,2},{3,4},{5,6}}; // succeeds
std::array <std::pair<int,int>, 3> a{{1,2},{3,4},{5,6}}; // fails to compile
}
Run Code Online (Sandbox Code Playgroud) 我有这个代码:
std::array<int,16> copyarray(int input[16])
{
std::array<int, 16> result;
std::copy(std::begin(input), std::end(input), std::begin(result));
return result;
}
Run Code Online (Sandbox Code Playgroud)
当我尝试编译此代码时,我收到此错误:
'std::begin': no matching overloaded function found
Run Code Online (Sandbox Code Playgroud)
和类似的错误std::end.
有什么问题以及如何解决?