我遇到了一个同事写的函数,它接受了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?
这看起来很整洁,但这不涉及复制向量来创建初始值设定项列表吗?
是的,这是正确的。
拥有一个接受一个或多个向量的函数不是更有效吗?
如果您愿意将v1
和v2
的内容移动到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) });
换句话说,您可以使用任一方法来获得相同的效果。