函数采用标准::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?

这看起来很整洁,但这不涉及复制向量来创建初始值设定项列表吗?

是的,这是正确的。

拥有一个接受一个或多个向量的函数不是更有效吗?

如果您愿意将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) });

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

相关内容

最新更新