标签:stdarray c c14 initialization
假设我有一个没有默认构造函数的类型A:
struct A
{
int x;
A(int x) : x(x) {}
};
我想创建一个A的std ::数组.我可以使用初始化列表轻松地创建它:
std::array<A, 5> arr = { 0, 1, 4, 9, 16 };
你可以在这里看到一个模式.是的,我可以使用生成器函数来计算数组的每个值:
int makeElement(size_t i)
{
return i * i;
}
std::array<A, 5> arr = {
makeElement(0),
makeElement(1),
makeElement(2),
makeElement(3),
makeElement(4)
};
是的,实际上我有超过5个元素(64,即).所以不重复makeElement 64次会很好.我提出的唯一解决方案是使用可变参数模板将参数包解压缩到初始化列表:https://ideone.com/yEWZVq(它还检查所有副本是否被正确删除).该解决方案的灵感来自this question.
它有效,但我不想滥用可变参数模板来完成这么简单的任务.你知道,膨胀的可执行文件大小,减慢编译速度,所有这些.我想做这样的事情:
>使用适当的大小创建一些未初始化的存储
>使用placement new初始化循环中的所有元素
>将存储转换为std :: array并将其返回
我可以做一些肮脏的黑客在动态内存中实现它:https://ideone.com/tbw5lm但这并不比std :: vector好,我根本没有这样的问题.
我不知道如何在自动记忆中做到这一点.即具有相同的方便函数返回std :: array的值与引擎盖后面的所有这些东西.有任何想法吗?
我想,boost :: container :: static_vector对我来说可能是个很好的解决方案.不幸的是,我无法使用boost来完成该特定任务.
PS.请注意,这个问题更像是研究兴趣.在现实世界中,可变参数模板和std :: vector都可以正常工作.我只是想知道也许我错过了什么.
解决方法:
我认为,你对代码膨胀的担忧被误解了.这是一个示例:
#include <utility>
#include <array>
template<std::size_t... ix>
constexpr auto generate(std::index_sequence<ix...> ) {
return std::array<int, sizeof...(ix)>{(ix * ix)...};
}
std::array<int, 3> check() {
return generate(std::make_index_sequence<3>());
}
std::array<int, 5> glob = generate(std::make_index_sequence<5>());
它产生非常整洁的组件:
check():
movl $0, -24(%rsp)
movl $1, -20(%rsp)
movl $4, %edx
movq -24(%rsp), %rax
ret
glob:
.long 0
.long 1
.long 4
.long 9
.long 16
如你所见,看不到任何代码膨胀.静态数组是静态初始化的,对于自动数组,它只是一堆移动.如果你认为一堆动作是一个可怕的代码膨胀,考虑它循环展开 – 每个人都喜欢!
顺便说一句,没有其他符合要求的解决方案.在构造时使用聚合初始化初始化数组,因此元素应该是默认可构造的或初始化的.
标签:stdarray,c,c14,initialization 来源: https://codeday.me/bug/20191007/1865429.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。