If you want the function to create the array for you, then return std::vector
by value.
Returning a reference, as your first example does, is either invalid (if the vector was a local variable that's now been destroyed) or weird and error-prone (since there's now a vector somewhere that needs managing somehow).
Returning a pointer, presumably to an allocated array, is error-prone since there's nothing to make sure the caller deallocates it correctly.
A more flexible alternative is to take an iterator range. It might make sense to overload it for both a pair of iterators:
std::vector<int> v(10); // non-empty vector
generate(v.begin(), v.end()); // replace existing elements
and an iterator and a size:
std::vector<int> v; // empty vector
generate(back_inserter(v), 10); // insert new elements
Note that the C++11 library has a std::iota
which acts like the first version (and can be used to implement any of these), but nothing like the second.