标签: stdvector

是否无法将 std::vector<T> 转换为 std::initializer_list<T> ?

我本来以为有人能做到这一点?然而,情况似乎并非如此。为什么?或者我做错了什么?

#include <vector>
#include <initializer_list>
#include <iostream>

using namespace std;

void fn(std::initializer_list<int> i)
{
  for(int ivalue:i)
  {
    cout << ivalue << endl;
  }
}

int main()
{
  fn({1,2,3});
  fn(vector<int>{4,5,6})
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

演示

我问这个问题的原因是因为我有一个类需要一个初始化列表,并且我是从它派生的,但需要在将初始化列表传递到基类之前对其进行处理。我怎样才能做到这一点?

c++ vector stdvector initializer-list c++11

5
推荐指数
1
解决办法
1918
查看次数

警告:有符号和无符号整数表达式之间的比较 [-Wsign-compare]

当我使用 g++ 编译 C++ 程序时

warning: comparison between signed and unsigned integer expressions [-Wsign-compare]
         for ( int i=0; i< myvec->size(); i++ ){
                                       ^
Run Code Online (Sandbox Code Playgroud)

其中myvec是 的对象std::vector<float>。

为了迭代 std::vector 中的元素,我需要处理警告吗?谢谢。

c++ stdvector

5
推荐指数
1
解决办法
7322
查看次数

std 函数替换向量中的字节范围

我有一个字节向量 (std::vector ): [1,1,1,9,9,9,1,1,1]

我想用未知长度的字节替换字节 3-6(我会在运行时知道)。因此向量的长度可能会增长、缩短或保持不变。但我知道我想要替换的字节的起点和终点。

我可以使用擦除或插入来调整大小,然后将新数据循环到旧数据上。

std::replace 进行搜索并替换匹配字节,而我知道要替换哪些字节。而 std::replace 似乎只替换一个元素。我想用数据块替换。

当然有一个 std 函数可以“巧妙”地做到这一点?(如果我愿意的话,我会叫你雪莉)。

c++ stdvector

5
推荐指数
1
解决办法
3802
查看次数

如何解释 sizeof(std::vector&lt;int&gt;) 的值?

为了了解std::vector<int>我写的内存消耗:

std::cout << sizeof(std::vector<int>) << std::endl;
Run Code Online (Sandbox Code Playgroud)

这产生32. 我试图理解这个价值从何而来。有些人查看了std::vector存储指针的源代码_MyFirst,_MyLast并_MyEnd解释了 24 字节的内存消耗(在我的 64 位系统上)。

最后一个字节怎么样8?据我了解,存储的分配器不使用任何内存。另外,这可能是实现定义的(是吗?),所以这可能有帮助:我正在使用 MSVC 2017.5。我不保证通过查看代码找到所有成员;该代码对我来说看起来非常混乱。

一切似乎都很好地对齐,但答案可能如下?:为什么结构体的 sizeof 不等于每个成员的 sizeof 之和?。但我用一个简单的测试它struct Test { int *a, *b, *c; };满足sizeof(Test) == 24.


一些背景

在我的程序中,我将有很多向量,但似乎其中大部分都是空的。这意味着关键的内存消耗来自空状态,即堆分配的内存不是那么重要。

一个简单的“仅用于此用例”向量很快就实现了,所以我想知道我是否遗漏了任何东西,无论如何我都需要 32 字节的内存,即使使用我自己的实现(注意:我很可能不会实现我自己的,这只是好奇心)。


更新

我用以下结构再次测试了它:

struct Test
{
    int *a, *b, *c;
    std::allocator<int> alloc;
};
Run Code Online (Sandbox Code Playgroud)

现在给了sizeof(Test) == 32。看起来,即使std::allocator没有消耗内存的成员(我认为),它的存在也会将Test …

c++ stl vector sizeof stdvector

5
推荐指数
1
解决办法
1309
查看次数

如果元素类型是基元,std::vector::resize() 向下花费 O(1) 时间吗?

据我了解,在 C++ 中,std::vector::resize当新大小较小时不分配新内存。此外,如果元素类型是具有析构函数的用户定义类,则可以为调整大小中“丢失”的每个元素调用该析构函数,因此在这种情况下,运行时间将与大小差异呈线性关系。

但是,如果元素类型是原语,例如std::vector<int>,则无需调用析构函数。在这种情况下,是否有任何理由认为resize向下不会是 O(1) 时间?

c++ memory-management stdvector

5
推荐指数
1
解决办法
682
查看次数

访问向量的后一位元素地址的有效方法

我想实现一个迭代器以在 for range 循环中使用自定义类。迭代器访问基类的内部std::vector并std::unique_ptr返回指向子类的原始指针。

这就是我想出的:

using upBase = std::unique_ptr<Base>;

class Test
{
   std::vector<upBase> list;
public:
   void Add(upBase&& i) { list.push_back(std::move(i)); }

   class iterator
   {
      upBase* ptr;
   public:
      iterator(upBase* p) : ptr(p)   {}
      bool         operator!=(const iterator& o) { return ptr != o.ptr; }
      iterator&    operator++()      { ++ptr; return *this; }
      Child&       operator*()       { return *(Child*)(*ptr).get(); }
      const Child& operator*() const { return *(Child*)(*ptr).get(); }

   };
   iterator begin() { return iterator(&list[0]); }
   iterator end()   { return iterator(&list[list.size()]); } …
Run Code Online (Sandbox Code Playgroud)

c++ algorithm iterator class stdvector

5
推荐指数
1
解决办法
96
查看次数

如何使 std::vector 使用已分配的内存为其内部数组?

有没有办法将已经初始化的数据移动到 a 中std::vector?

这是我自己的简单vec课程:

template<typename T>
class vec final
{
    std::unique_ptr<T[]> pValues;
    size_t size = 0;
public:
    std::span<T> span() const { return std::span<int>(pValues.get(), size); }
    vec(T* p, size_t sz) : size(sz) { pValues.reset(p); }
};
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,它将获得传递给它的内存的所有权:

int main()
{
    constexpr size_t count = 99;
    auto orig = std::make_unique<int[]>(count);
    {
        std::span<int> orig_(orig.get(), count);
        std::iota(orig_.begin(), orig_.end(), -1);
        assert((orig_[0] == -1) && (orig_[1] == 0) && (orig_[98] == 97));
    }

    vec<int> nums(orig.release(), count);
    auto nums_ = nums.span();
    assert((nums_[0] == …
Run Code Online (Sandbox Code Playgroud)

c++ stdvector

5
推荐指数
1
解决办法
1005
查看次数

“std::vector”的恒定时间“包含”?

我正在使用一些代码,通过将其地址与描述数据std::vector范围的地址进行比较,检查是否在恒定时间内包含给定元素。vector然而我怀疑,虽然它有效,但它依赖于未定义的行为。如果该元素不包含在 中,vector则不允许进行指针比较。

bool contains(const std::vector<T>& v, const T& a) {
  return (v.data() <= &a) && (&a < v.data() + v.size());
}
Run Code Online (Sandbox Code Playgroud)

我相信这是未定义的行为吗?如果是这样,有没有办法在不大幅改变代码时间复杂度的情况下做同样的事情?

c++ contains time-complexity stdvector undefined-behavior

5
推荐指数
1
解决办法
550
查看次数

C++14 和 C++17 赋值运算符的奇怪差异

我有以下代码:

#include <vector>
#include <iostream>

std::vector <int> a;

int append(){
  a.emplace_back(0);
  return 10;
}

int main(){
  a = {0};
  a[0] = append();
  std::cout << a[0] << '\n';
  return 0;
}
Run Code Online (Sandbox Code Playgroud)

该函数append()的副作用是将向量大小增加一。由于向量的工作方式,当超出其容量时,可能会触发其内存的重新分配。

因此,在执行 时a[0] = append(),如果发生重新分配,则 thena[0]无效并指向向量的旧内存。因此,您可以预期向量最终会变为,{0, 0}而不是{10, 0},因为它分配给旧向量a[0]而不是新向量。

让我感到困惑的是,这种行为在 C++14 和 C++17 之间发生了变化。

在 C++14 上,程序将打印 0。在 C++17 上,它将打印 10,这意味着a[0]实际上分配了 10。所以,我有以下问题,但我找不到答案:

  • C++17 是否a[0]在评估赋值表达式的 RHS 之后评估 的内存地址?C++14 之前是否对此进行了评估,这就是它发生变化的原因?
  • 这是 C++17 中修复的错误吗?标准发生了什么变化?
  • 使用 C++14 或 C++11 …

c++ stdvector assignment-operator c++14 c++17

5
推荐指数
1
解决办法
411
查看次数

std::vector 的存储何时自动收缩?

https://en.cppreference.com/w/cpp/container/vector说:

矢量的存储是自动处理的,根据需要扩展和收缩。

但我找不到“根据需要”发生收缩的情况。任何收缩操作都不会收缩 std::vector 的容量:

清除():

保持向量的capacity()不变

调整大小():

当调整到更小的尺寸时,向量容量永远不会减少,因为这会使所有迭代器无效

擦除():

在擦除点或擦除点之后使迭代器和引用无效,包括 end() 迭代器。

这意味着擦除点之前的迭代器和引用不会失效,如果容量更改则不会出现这种情况。

pop_back() :

迭代器和对最后一个元素的引用以及 end() 迭代器均无效。

这同样适用于此。

Shrink_to_fit() 确实收缩了 std::vector,但它是在 C++11 中添加的,并且上面的句子(“并且收缩”)没有标记为仅适用于 C++11 及更高版本。此外,对shrink_to_fit()的显式调用不是自动的(“矢量的存储是自动处理的”)并且不会“根据需要”发生。

那么 std::vector 何时自动收缩其存储空间呢?

c++ memory-management vector stdvector

5
推荐指数
1
解决办法
151
查看次数