函数取 std::initializer_list

Function taking std::initializer_list

我遇到了一位同事编写的接受初始化列表 std::vectors 的函数。我简化了演示代码:

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

这样的函数将允许您使用初始化列表的大括号调用这样的函数:

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

这看起来不错,但这不涉及复制向量来创建初始化列表吗?拥有一个接受一个或多个向量的函数不是更有效吗?因为您可以移动向量,所以这将涉及更少的复制。像这样:

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);

通过初始化列表传递对于像 int 和 float 这样的标量类型可能很有用,但我认为应该避免像 std::vector 这样的类型,以避免不必要的复制。最好按预期使用 std::initializer_list 作为构造函数?

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?

如果你愿意移动v1v2的内容到std::vector<std::vector<int>>,你可以在使用时做同样的事情std::initializer_list 也是。

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

换句话说,您可以使用任何一种方法来获得相同的效果。