Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to enable move semantics when adding custom objects to a vector?

Below code passes objects that contain big vectors into a vector. I want this to be performant. Do I need to cast test to rvalue in the call to push_back? Do I need to tell compiler how to move instances of struct Test? Or does this all go automatically?

int main()
{
    struct Test
    {
        std::vector<size_t> vals;
        double sum;
    };
    std::vector<Test> vecOfTest;
    vecOfTest.reserve(100000);

    for (size_t i = 0; i < 100000; i++)
    {
        Test test{};
        test.vals.reserve(i);
        for (size_t j = 0; j < i; j++)
        {
            test.vals.push_back(j);
            test.sum += j;
        }
        vecOfTest.push_back(test);
    }


    return 0;
}
like image 382
willem Avatar asked May 03 '19 07:05

willem


1 Answers

I want this to be performant

Following should be good enough. I hope the comments will help you to understand the code.

#include <vector>
#include <iostream>
#include <numeric>

struct Test
{
    std::vector<size_t> vals;
    double sum = 0; // initialing is a good idea
    Test(const size_t v, const double res) // provide constructor(appropriate one)
        : vals(v), // tell the size of the vals directly in the constructor
          sum(res) 
    {}
};

int main()
{

    std::vector<Test> vecOfTest;
    vecOfTest.reserve(100000);

    for (size_t i = 0; i < 100000; i++)
    {
        // Test& last_test = vecOfTest.emplace_back() needs C++17, otherwise
        // use std::vector::back()
        auto& last_test = vecOfTest.emplace_back(   // create the Test object in place and take the reference to it
            i,                     // tell the size of vals in newly creating Test object
            ((i - 1) * i) / 2.0    // ((j-1) * j)/2 = sum from 0 to j-1
        );
        std::iota(std::begin(last_test.vals), std::end(last_test.vals), static_cast<size_t>(0)); // populate, 0 to size of vals
    }
    return 0;
}
like image 134
User Using Avatar answered Oct 18 '22 16:10

User Using