dimanche 18 août 2019

Function accepting std::initializer_list

I came across a function a colleague had written that accepted an initializer list of std::vectors. I have simplified the code for demonstration:

int sum(const std::initializer_list<std::vector<int>> list)
{
    int tot = 0;
    for (auto &v : list)
    {
        tot += v.size();
    }
    return tot;
}

Such a function would allow you call the function like this with the curly braces for the initializer list:

std::vector<int> v1(50, 1);
std::vector<int> v2(75, 2);
int sum1 = sum({ v1, v2 });

That looks neat but doesn't this involve copying the vectors to create the initializer list? Wouldn't it be more efficient to have a function that takes a vector or vectors? That would involve less copying since you can move the vectors. Something like this:

int sum(const std::vector<std::vector<int>> &list)
{
    int tot = 0;
    for (auto &v : list)
    {
        tot += v.size();
    }
    return tot;
}

std::vector<std::vector<int>> vlist;
vlist.reserve(2);
vlist.push_back(std::move(v1));
vlist.push_back(std::move(v2));
int tot = sum2(vlist);

Passing by initializer list could be useful for scalar types like int and float, but I think it should be avoided for types like std::vector to avoid unnecessary copying. Best to use std::initializer_list for constructors as it intended?

Aucun commentaire:

Enregistrer un commentaire