I have a templated function, which takes an std::array
of arbitrary size as an argument. It looks roughly like this:
template <size_t n>
void foo(const std::array<int, n>& numbers) {
for (const auto & number: numbers) {
// ... do stuff ...
}
}
I can call it e.g. like so:
std::array<int, 2> ints = {4, 5};
foo(ints);
and everything is fine.
Unfortunately I cannot call the function directly using an initializer list. This code:
foo({4, 5});
gives me the following error:
error: no matching member function for call to 'foo' note: candidate template ignored: couldn't infer template argument 'n'
Is there a way to make my function work using an initializer list or something similar?
{/*..*/}
has no type and so cannot be deduced in template function except for std::initializer_list<T>
and for C-arrays T (&a)[N]
.
So you have to
add overload to handle std::initializer_list<int>
or C-array.
// span (C++20) has constructor from std::array :)
void foo(const std::span<int>& numbers) {
for (const auto & number: numbers) {
// ... do stuff ...
}
}
void foo(std::initializer_list<int> numbers) {
foo(std::span{numbers.begin(), numbers.size()});
}
or provide non deduced template parameter: foo<2>({4, 5});
or provide type to {}
(easier with CTAD of C++17): foo(std::array{4, 5});