I want to add many strings to a vector, and from what I've found, calling reserve() before this is more efficient.
If you know up front how many strings you want to store in the vector, then yes.
For a vector of ints, this makes sense because int is 4 bytes, so calling reserve(10) clearly reserves 40 bytes.
Yes, as it is allocating memory for sizeof(int) * 10 bytes.
I know the number of strings, which is about 60000. Should I call vector.reserve(60000)?
Yes.
How would the compiler know the size of my strings, as it doesn't know if these strings are of length 5 or 500?
The compiler doesn't need to know the length of the strings. Obviously, that is not known until runtime. However, that length doesn't change the compile-time size of the std::string class itself, which has a fixed layout and size. But one of its data members is a pointer to the actual character data, which is typically stored elsewhere in dynamic memory, thus is not counted toward the memory of the std::string object itself.
However, in the case of Short-String Optimization, the std::string class includes a small fixed buffer, which does count towards its fixed size at compile-time, and its data pointer will point at that buffer until the character data grows beyond the size of the buffer, then std::string will allocate dynamic memory to hold the larger character data. The SSO buffer still exists in the object, just unused at that point.
reserve() will allocate space only for the std::string objects themselves, not for any dynamic memory used for their character data. When a std::string object points at dynamic memory for its character data, that is irrelevant to the memory that std::vector allocates.
So yes, you would call reserve(60000) if you want to reserve space for 60000 std::string objects. That would allocate memory for sizeof(std::string) * 60000 bytes in the vector.
So, in general, reserve() allocates sizeof(vector::element_type) * capacity number of bytes. Then the vector creates instances of the element_type inside that memory as needed.
Or, in other words, when you want to pre-allocate memory for n number of elements, you ask reserve() to allocate memory for n number of elements. Period. The details of what those elements do internally is irrelevant to the vector. That is for the elements to handle on their own.