Passing primitive array to function with std::initializer

With the a function taking std::initializer_list as argument like shown below

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

This code works

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

but not this

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

Why does the second form not work? Or am I doing something wrong?

Edit:
From the gcc 4.7.2 implementation of std::intializer_list, the constructor of intializer_list is private and compiler needs to pass the size of the array.

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

I guess the compiler cannot judge the size of the array from the variable "i" in certain cases. If so, passing static array to intializer_list cannot be supported by the compiler (?).


i is not an initializer_list . initializer_list is not some shorthand for "static array". It's a special object that can only be created (outside of copy-construction) by using a braced-init-list (ie: {...} syntax).

When you do int i[] = {...}; you are performing aggregate initialization on an array. i is an array of int s, not an initializer_list .

What you want is a template function, which can take anything you can use range-based-for over:

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

You can do the index tuple trick, as used by many people before

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

Usage is easy

make_list(i, &sumOf);

Or using a lambda

make_list(i, [](std::initializer_list<int> x) {
  return sumOf(x);
});
链接地址: http://www.djcxy.com/p/83736.html

上一篇: = default忽略访问说明符?

下一篇: 传递基本数组以使用std :: initializer函数