Moving elements from std::vector<T1> to std::vector<std::pair<T1,T2>>

158 Views Asked by At

What is the most correct and efficient way to std::move elements from a vector of a certain type (T1) into a vector of an std::pair of that same type (T1) and another type (T2)?

In other words, how should I write MoveItems()?

#include <iostream> // For std::string
#include <string>   // For std::string
#include <vector>   // For std::vector
#include <utility>  // For std::pair

using std::vector;
using std::string;
using std::pair;

vector<string> DownloadedItems;
vector<pair<string,bool>> ActiveItems;

vector<string> Download()
{
    vector<string> Items {"These","Words","Are","Usually","Downloaded"};
    return Items;
}

void MoveItems()
{
    for ( size_t i = 0; i < DownloadedItems.size(); ++i )
        ActiveItems.push_back( std::pair<string,bool>(DownloadedItems.at(i),true) );
}

int main()
{
    DownloadedItems = Download();
    MoveItems();
    return 0;
}

Thank you for your time and help, I truly appreciate it!

2

There are 2 best solutions below

0
T.C. On BEST ANSWER
void MoveItems()
{
    ActiveItems.reserve(DownloadedItems.size());
    for (auto& str : DownloadedItems)
        ActiveItems.emplace_back(std::move(str), true);
}

N.B.: For strings as small as the ones in your example, moving may have the same cost as copying due to SSO, or perhaps even slightly more expensive if the implementation decides to empty out the source anyway.

2
druckermanly On

Some things you can do:

At the start of MoveItems(), call ActiveItems.reserve(DownloadedItems.size());. This prevents your array from resizing while you push things into it.

Instead of calling push_back call emplace_back. Here is an explanation of the advantages of doing so.

Worth noting, in this example, you can stop the copy into a new data structure by just constructing the std::pair from the start, and not copying data.