If I am writing a library and I have a function that needs to return a sequence of values, I could do something like:
std::vector<int> get_sequence();
However, this requires the library user to use the std::vector<> container rather than allowing them to use whatever container they want to use. In addition, it can add an extra copy of the returned array (depending on whether the compiler could optimize this or not) that might have a negative impact on performance.
You could theoretically enable the use of arbitrary containers (and avoid the unnecessary extra copying) by making a templated function that takes a start and an end iter:
template<class T_iter> void get_sequence(T_iter begin, T_iter end);
The function would then store the sequence values in the range given by the iterators. But the problem with this is that it requires you to know the size of the sequence so you have enough elements between begin
and end
to store all of the values in the sequence.
I thought about an interface such as:
template<T_insertIter> get_sequence(T_insertIter inserter);
which requires that the T_insertIter be an insert iterator (e.g. created with std::back_inserter(my_vector)
), but this seems way too easy to misuse since the compiler would happily accept a non-insert iterator but would behave incorrectly at run-time.
So is there a best practice for designing generic interfaces that return sequences of arbitrary length?