Передача примитивного массива в функцию с аргументом std :: initializer_list

С функцией a, принимающей std :: initializer_list в качестве аргумента, как показано ниже

int sumOf(std::initializer_list<int> numbers) {
int sum = 0;
for (auto x : numbers) {
sum += x;
}
return sum;
}

Этот код работает

auto sum = sumOf({ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 });

но не это

 int i[]  = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
auto x = sumOf(i);

Почему вторая форма не работает? Или я что-то не так делаю?

Редактировать:
Из реализации std :: intializer_list в gcc 4.7.2 конструктор intializer_list является приватным, и компилятор должен передать размер массива.

  // The compiler can call a private constructor.
constexpr initializer_list(const_iterator __a, size_type __l)
: _M_array(__a), _M_len(__l) { }

Я предполагаю, что компилятор не может судить о размере массива по переменной «i» в некоторых случаях. Если это так, то передача статического массива в список intializer_list не может поддерживаться компилятором (?).

0

Решение

i это не initializer_list, initializer_list не является сокращением для «статического массива». Это специальный объект, который может быть создан только (вне конструкции копирования) с помощью списка фигурных скобок (например: {...} синтаксис).

Когда вы делаете int i[] = {...}; вы выполняете агрегатную инициализацию на массив. i это массив intс не initializer_list,

То, что вы хотите, это шаблонная функция, которая может принимать все, что вы можете использовать на основе диапазона для более:

template<typename Rng>
int sumOf(const Rng &numberRange) {
int sum = 0;
for (auto x : numberRange) {
sum += x;
}
return sum;
}
2

Другие решения

Вы можете сделать трюк с индексным кортежем, как раньше использовали многие

template<int N, int ...X>
struct I : struct I<N-1, N, X...> {};

template<int X...>
struct I<0, X...> {
typedef I type;
};

template<typename F, typename T, int N, int ...X>
decltype(f(std::declval<std::initializer_list<T>>()))
make_list(T const (&a)[N], F f, I<X...>)
{
return f(std::initializer_list<T>{a[X]...});
}

template<typename F, typename T, int N>
decltype(f(std::declval<std::initializer_list<T>>()))
make_list(T const(&a)[N], F f) {
return make_list(a, f, typename I<N-1>::type());
}

Использование легко

make_list(i, &sumOf);

Или используя лямбду

make_list(i, [](std::initializer_list<int> x) {
return sumOf(x);
});
1

По вопросам рекламы [email protected]