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忽略访问说明符?