Я попытался сделать базовую функцию data()
для типа std :: initalizer_list, чтобы извлечь данные из списка. Однако, пробовав его в основной суммарной функции 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();
}
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);
Эта функция
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];
Также я не вижу смысла в вашем изобретении.
Используйте простые решения, а не свернутые.
#include <numeric>
template<typename T>
T sum(std::initializer_list<T> vals)
{
return std::accumulate(vals.begin(), vals.end(), T{});
}
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; }
и разрешить доступ к элементам по индексу