【问题标题】:Iterate an std::vector by capacity按容量迭代 std::vector
【发布时间】:2015-12-31 18:26:57
【问题描述】:

当我在预先知道最终大小的情况下填充 std::vector 时,我通常会提前保留其容量以避免重新分配其内容(在 C++03 中,这涉及为已存储在 @987654323 中的每个对象调用复制构造函数@)。

这是一个简单的例子:

std::vector<std::string> v;
v.reserve(10);    

for( std::vector<std::string>::size_type i = 0, capacity = v.capacity();
     i < capacity;
     ++i )
{
    v.push_back(std::to_string(i));
}

有更好的方法(更少的 C 风格)来循环 std::vector 容量?

我正在寻找 C++03 和 C++11 的答案。

编辑:我重写了示例,因为所有答案和 cmets 都偏离了主题,仅涉及用数组填充 std::vector,这不是问题的重点。

【问题讨论】:

  • 比什么更好?你想避免的当前fill有什么问题?
  • 您可能只是想将数组转换为向量? stackoverflow.com/questions/8777603/…
  • 它只适用于std::vector&lt;T&gt; v(t, t + size);
  • @Lorenzo,什么是“循环容量”???
  • @Lorenzo:请注意,在您的std::vector::reserve(n) 之后,容量可能大于n,因此您将向量填充为特定于实现的大小...

标签: c++ stdvector


【解决方案1】:

您根本不需要循环。 std::vector 构造函数的重载需要两个迭代器。所以只需使用std::beginstd::next 来获取传入数组的开始和结束,并从中创建一个向量。

template<typename T>
std::vector<T> fill(const T* t, size_t size)
{
    return {std::begin(t), std::next(std::begin(t), size)};
}

同样你可以使用指针算法,这就是上述方法本质上所做的:

template<typename T>
std::vector<T> fill(const T* t, size_t size)
{
    return {t, t + size};
}

【讨论】:

  • 引擎盖下仍然存在一个循环,并且由于问题以“保留”开头,我感觉 OP 是在谈论性能?...还不确定。
  • @Sergey - 如果向量构造函数比使用储备更糟糕,你应该向库开发者要求退款。
  • @BoPersson,如果我免费得到它会很难 :) 但这不是我的意思。我想说的是,我的第一印象是 OP 正在尝试找到比保留 + 循环更高效的解决方案。可能我错了。我仍然不确定他们想要什么。
  • @CoryKramer:谢谢你的回答,但它离题了......我不是在寻找一种用数组填充向量的方法(这只是一个例子,现在我改变了代码为了更好地反映我的问题),问题是关于迭代 capacity()std::vector
【解决方案2】:

在 c++11 或更高版本中,如果你填充一个知道其大小的向量 std::initializer_list 将是你最好的选择。

您可能希望避免通过指向 const 对象数组的指针进行初始化,因为这几乎可以保证副本。我很欣赏这在 c++03 中是必要的,如果可能的话,这应该是您迁移到更新编译器的主要动机之一。

所以:

std::vector<Thing> mythings { Thing(1), Thing(2), Thing(3) };

几乎是你能得到它的最快速度。 (并不是说不需要填充功能)。

如果您在具有优化功能的现代编译器上编译它,您会发现Things 实际上会在向量中就地创建。没有更快的方法。

【讨论】:

    猜你喜欢
    • 2012-05-07
    • 2011-01-13
    • 1970-01-01
    • 2017-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多