Ошибка функции data () в C ++ std :: initializer_list

0

Я попытался сделать базовую функцию 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();
}
  • 0
    Зачем вам вообще нужна функция данных? Похоже, вы пытаетесь смешивать Java, C и C ++ 11 в плохой форме.
  • 0
    @ 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; } и разрешить доступ к элементам по индексу
Показать ещё 3 комментария
Теги:

3 ответа

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);

Демо-версия

  • 0
    данные не являются массивом. Это указатель. Определяется как _Ty * данные
  • 0
    @VladfromMoscow Исправлено
0

Эта функция

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];

Также я не вижу смысла в вашем изобретении.

  • 0
    Я попробовал это сначала, и это не сработало, поэтому я сделал цикл в моей Q, хотя я знал, что это неправильно
  • 0
    @ Джозеф Смотрите мой обновленный пост.
Показать ещё 3 комментария
0

Используйте простые решения, а не свернутые.

#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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню