C++ std::initializer_list data() 函数错误
Posted
技术标签:
【中文标题】C++ std::initializer_list data() 函数错误【英文标题】:C++ std::initializer_list data() function error 【发布时间】:2014-02-20 18:03:32 【问题描述】:我尝试为 std::initializer_list 类型创建一个基本的data()
函数以从列表中提取数据。但是,在sum(1, 2, 3, 4)
的基本求和函数中尝试它时,我得到的结果是1447450180
而不是10
:
template < typename _Ty > const _Ty *data(const std::initializer_list<_Ty> &_List)
_Ty *data = new _Ty[_List.size()];
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); ++i, *data++ = *i);
return data;
int sum(std::initializer_list<int> numbers)
int total = 0;
for(int i = 0; i < numbers.size(); ++i, total += data(numbers)[i]);
return total;
int main()
std::cout << sum(1, 2, 3, 4);
getchar();
【问题讨论】:
为什么还需要数据功能呢?您似乎正试图以一种糟糕的方式混合 Java、C 和 C++11。 @LB-- 更容易而不是写int sum(std::initializer_list<int> numbers) int total = 0; for(typename std::initializer_list<int>::iterator i = numbers.begin(); i != numbers.end(); ++i) total += *i; return total;
,并允许通过索引访问元素
你并没有让它变得更容易,而是让它变得更加复杂。看起来您不太了解迭代器,而且您似乎肯定不了解如何使用初始化列表。
@LB--:我非常了解如何使用迭代器,但是,我刚刚开始使用 initalizer_lists。
@Joseph 你是否意识到对data()
的每次调用 都会分配内存(并泄漏它)然后复制初始化程序列表的内容?这很容易成为重新实现 std::accumulate
的最糟糕的方法
【参考方案1】:
2 个错误:
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); ++i, *data++ = *i);
您正在递增 data
指针,它会跳过先前分配的内存。创建一个count
变量:
int count = 0;
data[count++] = *i
但是现在您正在跳过循环的第一个元素,因为您先递增然后取消引用。换个顺序。最终循环应如下所示:
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); data[count++] = *i, ++i);
Live Demo
【讨论】:
数据不是数组。它是一个指针。它定义为 _Ty *data @VladfromMoscow 已修复【参考方案2】:使用简单的解决方案,而不是复杂的解决方案。
#include <numeric>
template<typename T>
T sum(std::initializer_list<T> vals)
return std::accumulate(vals.begin(), vals.end(), T);
http://coliru.stacked-crooked.com/a/524ffb543683d901
【讨论】:
【参考方案3】:这个功能
template < typename _Ty > const _Ty *data(const std::initializer_list<_Ty> &_List)
_Ty *data = new _Ty[_List.size()];
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); ++i, *data++ = *i);
return data;
至少是无效的,因为存在内存泄漏。每次调用该函数时,它都会为数组数据分配新的内存,并且永远不会删除该数组。
此外,该函数返回数组之外的指针,因为在其中指针已更改,即它已递增。
你也不知道如何正确地编写循环。在这个循环中,您 1) 跳过序列的第一个元素,然后 2 尝试访问序列之外的元素。
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); ++i, *data++ = *i);
正确的循环看起来
for (typename std::initializer_list<_Ty>::iterator i = _List.begin();
i != _List.end(); ++i ) *data++ = *i;
第二个循环同样有效,因为它也是无效的
for(int i = 0; i < numbers.size(); ++i, total += data(numbers)[i]);
应该有
for(int i = 0; i < numbers.size(); ++i ) total += data(numbers)[i];
我也看不出你的发明有什么意义。
【讨论】:
我先试过了,但没用,所以我在 Q 中做了循环,即使我知道这是错误的 恐怕还是不行,为了反驳I do not see any sense in your invention.
,我创建了它,这样你就不必写出迭代器循环,也可以通过在data
函数上使用[]
运算符的索引
@Joseph 我创建它是为了让您不必写出迭代器循环——这正是<algorithm>
标头中大多数东西存在的原因!跨度>
以上是关于C++ std::initializer_list data() 函数错误的主要内容,如果未能解决你的问题,请参考以下文章
在 Visual C++ 编译器中使用 std::initializer_list 2012 年 11 月 CTP
使用 std::initializer_list 创建指向 std::min 的函数指针
为啥 `std::initializer_list` 不提供下标运算符?
为啥 std::min(std::initializer_list<T>) 按值接受参数?