Often something like Vector{typeof(f(zero(eltype(x))))}(undef,N) will work, but this may result in f(0) actually being called. Especially if f has side effects. Also, if f(0) returns a different type than f(1), there is obviously going to be problems.
I usually rely on functions like map to do the allocation for me. If I want to save allocations, I can use map! the second time around (with the array returned by map).