In C++11, this is the preferred way:
std::vector<X> f();
That is, return by value.
With C++11, std::vector has move-semantics, which means the local vector declared in your function will be moved on return and in some cases even the move can be elided by the compiler.