在C++ 11中,使用lambda/for_each,我们如何从end迭代一个数组?
我尝试了以下,但都导致无限循环:
for_each (end(A), begin(A), [](int i) {
....
});
for_each (A.rend(), A.rbegin(), [](int i) {
...
});
Run Code Online (Sandbox Code Playgroud)
任何的想法?谢谢.
C++标准对sizeof(std::array<char, N>)应该是什么(对于某些常量N)说了些什么?
在对不同问题的评论中,提到std::array并不总是"堆栈分配".该评论是对一个不同的评论的回应,该评论推测将过大的常量std::array声明为局部变量可能导致程序因"资源分配"变量的资源不足而中止.我假设后续评论意味着有可能std::array以某种方式切换到动态分配模式.
我可以想象,可能会有某种SFINAE应用于数组大小阈值,触发std::array实际动态分配数组并对其进行管理的特化.在这种情况下,sizeof(std::array<...>)可能只是指针的大小.这是允许发生的吗?
假设foo_t具有命名构造函数的类型,make_foo().现在,我想要真正拥有123个foo - 不多也不少.所以,我在考虑一个std::array<foo_t, 123>.现在,如果foo_t是默认构造的,我会写:
std::array<foo_t, 123> pity_the_foos;
std::generate(
std::begin(pity_the_foos), std::end(pity_the_foos),
[]() { return make_foo(); }
);
Run Code Online (Sandbox Code Playgroud)
而鲍勃是我的叔叔,对吗?不幸的是...... foo_t没有默认的ctor.
那么我应该如何初始化我的数组呢?我是否需要使用一些可变模板扩展伏都教?
注意:如果有帮助,答案可能会使用C++ 11,C++ 14或C++ 17中的任何内容.
我正在display()为容器类型创建一个方便的函数模板.最后一个元素的输出与其余元素不同,因此我检查何时myIterator != --cont.cend();.这适用于std::vector,但不适用std::array.为什么?
这是一个MWE(不是我的实际代码):
std::vector<double> vec({1,2});
std::array<double, 2> arr({{1,2}});
auto vecIt = --vec.end(); // OK
auto arrIt = --arr.end(); // error: lvalue required as decrement operand
Run Code Online (Sandbox Code Playgroud) 为什么std::array<std::string, 65536> a = {};在Core i7 9700K处理器上使用-O3进行gcc编译需要花费超过17分钟的时间?
我偶然发现了gcc的问题,我在头文件std::array中用std::strings 空初始化了a ,而不是在源文件中的专用构造函数中进行了初始化。该文件包含在多个位置,这导致了几乎无限的优化循环。随着-O0它迅速完成,但是-O1我在核心i7-9700K处理器上等待了一个多小时,而gcc仍在运行。
最后,我将问题缩小到std::array<std::string, N>其中N某个大数字的空初始化。对于其他类型的其他非平凡构造函数,在编译时间随元素数量线性增加的情况下,也可能会遇到类似的问题。像下面的例子。
#include <array>
struct A {
A() : i(0) {}
int i;
};
int main() {
std::array<A, 65536> a = {};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
为了自己解决这个问题,我将上面的代码编译为汇编代码。与-O0组装的样子的展开for呼叫的循环给构造与线作为阵列尺寸的约4倍的数量。启用优化时,似乎完全消除了初始化。
#include <array>
#include <string>
int main() {
std::array<std::string, 65536> a = {};
return 0;
}
Run Code Online (Sandbox Code Playgroud)
但是,当用替换数组的内容时std::string,std::string即使启用了优化,编译器似乎也无法删除的初始化。
我想这就是为什么我的初始构建陷入了无休止的优化循环的原因的一部分,但是它不能完全解释它,也不能解释为什么clang似乎能更好地处理这一问题。有没有人可以进一步阐明这个问题?
我尝试了几个gcc版本,从gcc-6到gcc-8。即使使用gcc-4.9,也需要花费一些时间,但花费的时间并不多,大约需要4.5分钟。在-stdlib = libstdc ++中使用clang会产生0m0,120s的编译时间。
假设我有一个数组:
std::array<int, 6> {4,3,2};
Run Code Online (Sandbox Code Playgroud)
在这种情况下,是否可能引发错误或警告?在某些情况下,使此显式匹配可能会很有用。
在 C++ 标准的 C++ 17 和 C++ 20 工作草案中,类模板的推导指南std::array定义如下
template<class T, class... U>
array(T, U...) -> array<T, 1 + sizeof...(U)>;
Run Code Online (Sandbox Code Playgroud)
例如这个声明的结果
std::array a = { 1ll, 2llu };
Run Code Online (Sandbox Code Playgroud)
应该被编译并且变量的推导类型a是std::array<long long, 2>.
然而,编译器使用另一个推导指南来检查所有初始值设定项是否具有相同的类型。
这是编译器的错误还是 C++ 17 和 C++20 标准中的推导指南确实发生了变化?
C++ 20包括std::span,其"描述了一个对象,该对象可以引用连续的对象序列,其中序列的第一个元素在零位置".它的界面非常接近std::array,虽然它支持动态范围和固定范围.
明显的区别是std::array拥有它的元素(因此它的析构函数会破坏它们)而std::span不是.
还有什么array可以用于那个span不可以吗?
请原谅我的无知,在我看来,这std::array意味着您的常规数组的 STL 替代品。但是因为数组大小必须作为模板参数传递,它阻止我们std::array使用仅在运行时已知的大小进行创建。
std::array<char,3> nums {1,2,3}; // Works.
constexpr size_t size = 3;
std::array<char,size> nums {1,2,3}; // Works.
const buf_size = GetSize();
std::array<char, buf_size> nums; // Doesn't work.
Run Code Online (Sandbox Code Playgroud)
我认为 C++ 中数组的一个非常重要的用例是基于运行时输入创建一个固定大小的数据结构(比如为读取文件分配缓冲区)。
我为此使用的解决方法是:
// Create a array pointer for on-the-spot usecases like reading from a file.
char *data = new char[size];
...
delete[] data;
Run Code Online (Sandbox Code Playgroud)
或者:
// Use unique_ptr as a class member and I don't want to manage the memory myself.
std::unique_ptr<char[]> myarr_ = std::unique_ptr<char[]>(new char[size]);
Run Code Online (Sandbox Code Playgroud)
如果我不关心固定大小,我知道我可以使用 …
我很想知道为什么static_assert下面代码中的第二个不起作用。似乎即使数组c是对 的引用a,数组的大小也嵌入在类型中,因此它应该在编译时可用。
#include <array>
int main()
{
std::array<int,2> a = {1,2};
std::array<int,2> b = {2,3};
std::array<int,2>& c = a;
static_assert(a.size() == b.size(), "a.size==b.size"); // ok size of array is compile time constant
static_assert(c.size() == a.size(), "c.size==a.size"); // compiler error "static_assert expression is not an integral constant expression"
}
Run Code Online (Sandbox Code Playgroud)