首页 > 解决方案 > 采用 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 用于构造函数?

标签: c++11initializer-list

解决方案


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

对,那是正确的。

使用一个或多个向量的函数不是更有效吗?

如果您愿意v1和的内容移动v2到 a 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) });

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


推荐阅读