使用std :: initializer_list参数传递原始数组

时间:2012-12-06 07:20:55

标签: c++ c++11 initializer-list

使用一个函数将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。

2 个答案:

答案 0 :(得分:2)

i不是initializer_listinitializer_list不是“静态数组”的简写。它是一个特殊的对象,只能通过使用braced-init-list(即:{...}语法)来创建(在复制构造之外)。

执行int i[] = {...};时,您正在数组上执行聚合初始化。 iint的数组,而不是initializer_list

你想要的是一个模板功能,可以使用任何你可以使用的基于范围的功能:

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

答案 1 :(得分:1)

你可以做许多人之前使用的索引元组技巧

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

或使用lambda

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