I want to define a function Foo
that takes as argument a few objects Widget
, whose number is only known at run time. The simplest signature would be:
void Foo(const std::vector<Widget>& widgets);
The function can be made more general by turning into a template and using iterators. However, if the Widget
s are not stored in some contiguous form, any signature based on array-of-values would force the caller to make a copy of each. For example, a copy is necessary if each Widget
is contained in some other object Holder
, or if Foo
needs to be called on just 3 widgets that come from idiosyncratic sources.
Copies can be avoided if the function accepts a vector of pointers:
void Foo(const std::vector<const Widget*>& widgets);
but this makes the function unsafe. For example in:
std::vector<const Widget*> widgets;
for (const auto& holder : holders) {
widgets.push_back(&holder.get_widget());
}
Foo(widgets);
forgetting the ampersand on const auto&
would lead to segfault.
I can think of a couple of solutions that are both safe and copy-free, involving lambdas or a Foo
template and custom iterators, but they are quite gross. What would be the best design for this situation?