I think people sometimes feel compelled to combine auto and the range based for loop when they shouldn't. In this example the range based for loop adds clarity but the use of auto doesn't. I would have written something like:
Actually, the only thing this tells you about what you are getting out of the vector is that it can be implicitly converted to a string.
If data is a vector of, for example, pointers to const char, on each iteration this code will unnecessarily copy each item into a temporary string before printing it. Using auto would avoid this step, regardless of data's type.
Note that the typical non-range-based for loop also omits the vector item type... Is this that much less clear?:
for (int i = 0; i < data.size(); ++i) {
ofile << data[i] << std::endl;
}