【问题标题】:How does C++ create different vectors in two dimensional vector initialization?C++如何在二维向量初始化中创建不同的向量?
【发布时间】:2020-04-14 02:44:49
【问题描述】:

我看到几个地方 (e.g) 可以像这样初始化 2-dim 向量

vector<vector<int> > vec(3, vector<int>(2, 0));

我在想的是这段代码被评估为以下

auto tmp = vector<int>(2, 0);
vector<vector<int> > vec(3, tmp);

如果我是正确的,那么vec 的 3 个元素都指的是同一个引用。 也就是说修改vec[0][1]也会修改vec[1][1]

如果我错了,C++如何使vec中每个元素的初始化成为不同的引用?

【问题讨论】:

  • 参数被复制,因此它们不会引用同一个对象。
  • 如果它们都指向同一个对象,那么修改三个元素中的任何一个都会导致整个对象被完全改变。
  • 你显然已经习惯了另一种默认引用语义的语言。在 C++ 中,值语义是默认值,因此默认值是 tmp 将被复制三次(创建三个不同的实例,它们都是 tmp 的副本)而不是引用三次。 (可以显式强制引用语义,但 std::vector 无法做到这一点)
  • @Peter 这意味着即使使用我的伪代码(后一个代码为tmp),vec 的所有 3 个元素也指不同的向量
  • 每个vector 都包含一个指向动态分配数组的指针,因此vector 是连续的。 vectorvectors 需要多个 vectors,每个都有自己的指针,指向自己的动态分配的数组。外部vector 包含一个指向内部vector 数组的指针,而每个内部vectors 包含一个指针,该指针执行包含其行或列数据的不同数组。

标签: c++ multidimensional-array vector std


【解决方案1】:

默认情况下,几乎所有 C++ 容器(包括 std::vector)都通过副本获取参数,因此:

auto tmp = vector<int>(2, 0);
vector<vector<int> > vec(3, tmp);

现在,向量创建了三个完全不相关的 'tmp' 副本并将其存储在自身内部。


但是请注意,您尝试做的事情是可能的,通过使用std::reference_wrapper,就像这样:std::vector&lt;std::reference_wrapper&lt;std::vector&lt;int&gt;&gt;&gt;

例子:

#include <vector>
#include <functional>
#include <iostream>

int main()
{
    auto tmp = std::vector<int>(2, 0);
    std::vector<std::reference_wrapper<std::vector<int>>> a(3, std::ref(tmp));
    a[0].get()[0] = 2;
    a[1].get()[1] = 10;
    a[2].get()[0] = 30;
    std::cout << "'tmp' contains: ";
    for (auto const& elem : tmp)
        std::cout << elem << " ";
}

输出:
'tmp' 包含:30 10

【讨论】:

    【解决方案2】:

    来自constructor 参考

    3) 使用具有值 value 的元素的 count 个副本构造容器。

    没有对tmp 的引用,只是副本。所有单个向量都是不同的,修改一个向量不会修改其他向量。

    【讨论】:

      猜你喜欢
      • 2013-11-04
      • 1970-01-01
      • 2021-10-02
      • 2011-12-13
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多