简体   繁体   中英

How to preserve capacity of vector elements on vector::clear()?

When I clear a vector<string> , the vector 's capacity is preserved, but the capacities of the individual string s in the vector are not preserved. Is there a way to achieve this?

I can't think of a way to achieve this in a straightforward, simple manner. Here is some test code which demonstrates what I'm trying to do:

#include <string>
#include <iostream>
#include <sstream>
#include <vector>

using namespace std;

int main()
{
    istringstream input;
    input.str(
R"(2
This is the first sentence.
And this is the second sentence.
3
Short text.
Another short text.
The end!
)");

    vector<string> lines;

    string line; // The capacity of this string is preserved throughout.
    while (getline(input, line))
    {
        int count = stoi(line);

        lines.clear(); // This clears capacity of the string elements too!
        for (int i = 0; i < count; ++i)
        {
            getline(input, line);
            lines.push_back(line);
        }

        // process/print 'lines' here.
    }

    return 0;
}

One way to preserve the capacities of the string elements would be to never clear the vector , and track the size of the vector manually. But that wouldn't be clean at all. Is there a clean solution to this problem?

Edit:

If I rearrange the code the following way, I'm able to preserve the capacities of the strings in the vector. However, this is very ugly. I'm looking for a clean solution.

    ...
    vector<string> lines;

    string line; // The capacity of this string is preserved throughout.
    while (getline(input, line))
    {
        int count = stoi(line);

        for (int i = 0; i < count; ++i)
        {
            if (i < lines.size())
            {
                getline(input, lines[i]);
            }
            else
            {
                lines.emplace_back();
                getline(input, lines.back());
            }
        }

        // process/print 'lines' here.
        // Size is 'count'.
    }
    ...

How to preserve capacity of vector elements on vector::clear()?

I can't think of a way to achieve this in a straightforward, simple manner.

That's because there isn't a straightforward way to achieve what you want. Once you destroy a string, its allocations are gone and there is no guaranteed way to get it back.

What you could do, is move the strings onto another vector prior to clearing the source vector. Then after clearing, you can move the strings back at your leisure. However while this technically would fulfill the requirement stated in the title, I don't see how that could be more useful to you than not clearing the vector in the first place.


I presume that you want to "preserve capacity" to avoid unnecessary allocation for the purpose of optimisation. Depending on what "processing" of the line means, it might be more efficient to not store them in a vector at all, but instead read the input until newline, process/print, then read the next line and so on. That way you only allocate a single string once (or a few times as the line grows up to the longest input line).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM