作者热门文章
- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
对于 C++11,STL 现在有一个 std::iota
函数(参见 reference)。但是,与 std::fill_n
、std::generate_n
相比,没有 std::iota_n
。什么是一个好的实现呢?直接循环(备选方案 1)或使用简单的 lambda 表达式委托(delegate)给 std::generate_n
(备选方案 2)?
备选方案 1)
template<class OutputIterator, class Size, class T>
OutputIterator iota_n(OutputIterator first, Size n, T value)
{
while (n--)
*first++ = value++;
return first;
}
备选方案 2)
template<class OutputIterator, class Size, class T>
OutputIterator iota_n(OutputIterator first, Size n, T value)
{
return std::generate_n(first, n, [&](){ return value++; });
}
这两种选择是否会生成具有优化编译器的等效代码?
更新:结合了@Marc Mutz 的优秀观点,在其目标点返回迭代器。这也是std::generate_n
与 C++98 相比,C++11 得到了更新。
最佳答案
作为一个随机示例,我使用 g++ -S -O2 -masm=intel
(GCC 4.7.1, x86_32) 编译了以下代码:
void fill_it_up(int n, int * p, int val)
{
asm volatile("DEBUG1");
iota_n(p, n, val);
asm volatile("DEBUG2");
iota_m(p, n, val);
asm volatile("DEBUG3");
for (int i = 0; i != n; ++i) { *p++ = val++; }
asm volatile("DEBUG4");
}
这里 iota_n
是第一个版本,iota_m
是第二个。在所有三种情况下,程序集都是这样的:
test edi, edi
jle .L4
mov edx, eax
neg edx
lea ebx, [esi+edx*4]
mov edx, eax
lea ebp, [edi+eax]
.p2align 4,,7
.p2align 3
.L9:
lea ecx, [edx+1]
cmp ecx, ebp
mov DWORD PTR [ebx-4+ecx*4], edx
mov edx, ecx
jne .L9
对于 -O3
,这三个版本也非常相似,但要长 很多(使用条件移动和 punpcklqdq
等) .
关于c++ - 什么是 iota_n 的良好实现(STL 中缺少算法),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11767512/
对于 C++11,STL 现在有一个 std::iota 函数(参见 reference)。但是,与 std::fill_n、std::generate_n 相比,没有 std::iota_n。什么是
我是一名优秀的程序员,十分优秀!