Reputation: 81
I have a function which accepts arbitrary iterable objects/containers:
auto iterate(auto&& iterable);
And it operates on them using range-based for-loops in a generic manner.
This works fine with standard containers, C-style arrays, and std::generator
, but it fails when I try to pass it an init-list:
iterate({1, 2, 3});
I get the error error: no matching function for call to ‘iterate(<brace-enclosed initializer list>)
and couldn’t deduce template parameter ‘auto:57’
.
How can I include initalizer lists in the considered candidates for deduction without writing a separate overload? I need it to be only one function because I also want to write iterator-based utilities that operate on multiple iterables, and I don't know how to write functions that would operate on all of them easily if I had to write multiple functions for each combination of ordinary iterable and init-list.
Upvotes: 1
Views: 108
Reputation: 25388
I know you want to avoid an overload, but since you are using C++20 or later, your best option looks to be to add one that delegates to your existing function by passing it a std::span
, like so:
template <class T> auto iterate
(std::initializer_list <T> il)
{
std::span s {il.begin (), il.end ()};
return iterate (s);
}
A span
is cheap to construct (might even be free, in this situation), but maybe adding an overload adds too much boilerplate, we don't have enough context to know.
Upvotes: 0