为啥我们不能在动态向量的情况下使用方括号?
Posted
技术标签:
【中文标题】为啥我们不能在动态向量的情况下使用方括号?【英文标题】:Why can't we use square brackets in case of dynamic vectors?为什么我们不能在动态向量的情况下使用方括号? 【发布时间】:2021-10-01 11:36:19 【问题描述】:#include <iostream>
using namespace std;
#include <vector>
#include <queue>
int main()
vector<int> *v = new vector<int>;
v -> push_back(1);
//min priority queue
priority_queue<int, vector<int>, greater<int>> pq;
pq.push(v[0]); //Able to do pq.push(v -> at(0))
那么为什么会出现错误?我不是在我的优先级队列中推送一个整数吗?
【问题讨论】:
v
是(不必要的)一个指针。 v[0]
正在推迟该指针。您正在尝试将 vector<int>
推送到 int
的优先级队列中
不要动态分配向量。向量确实已经动态分配了它的元素,因此(几乎)没有充分的理由使用new std::vector<int>;
@Aman pq.push 将只接受一个 int 作为输入。在您的情况下,v[0] 将返回整个向量* ( v + 0) == *(v) == *v
这只是取消引用指针,而不是访问向量的元素
@Aman 现在我明白你的困惑了;)。 std::vector
不是数组。 arr[0] == *( arr + 0) == *arr
。第一个元素与第一个元素具有相同的地址,因此 dereferencign arr
为您提供第一个元素。 vector
的情况并非如此
【参考方案1】:
标准向量已经动态管理其缓冲区。
在 99.9% 的情况下,new std::vector
是一个错误。
vector<int> v;
v.push_back(1);
//min priority queue
priority_queue<int, vector<int>, greater<int>> pq;
pq.push(v[0]);
这行得通。
如果您确实在 0.1% 的情况下认为新向量有意义,请将 v[0]
更改为 (*v)[0]
。
v[0]
所做的是将指针 v
视为指向向量数组的指针。然后它选择第 0 个。它不会选择第 0 个元素的第 0 个元素。 v[0][0]
也可以工作(但当v
实际上不是指向数组的指针时,这样做会很糟糕;通常会让读者感到困惑)。
所以C++从C继承了一个数组指针对偶性。当你有一个指针时,你可以用方括号把它当作一个数组来对待,就好像它是指向数组第一个元素的指针一样。这实际上是数组[]
的工作原理;数组被隐式转换为指针,然后 []
应用。当您有一个未指向数组的指针时,这会令人困惑。
C++ 也有对象,这些对象可以重载方括号等运算符。重载发生在对象上而不是指向这些对象的指针上。
所以vector[]
伪装成一个数组并找到向量所拥有的元素。 ptr_to_vector[]
insteat 将其视为从 *ptr_to_vector
开始的向量数组,几乎不是您想要的。
C++ 在拥有可以是值的完整对象方面是相对独特的。很少有语言可以。如果您来自其他语言,这可能会令人困惑。尽可能采用 C++ 中的值语义。
【讨论】:
new std::vector is a mistake.
完全取决于上下文。他的问题是为什么在这种情况下他的编译失败了。
@StoicaMircea 在问题的上下文中,可能在所有其他上下文中的 99.9% 中,这是一个错误。正如答案中已经提到的。它并不完全依赖。
@super in 99.99% 是使用向量的错误。如下使用数组:int v[1] = 1;
。这是你的答案。当您知道自己在做什么时,没有什么是错误的。【参考方案2】:
这将修复你的编译
pq.push((*v)[0]);
因为 v 是指向 vector<int>
的指针。
在这种情况下,pq.push
将只接受一个 int 作为输入。 v[0]
将返回一个 vector<int>
对象。如果您真的想使用 [] 索引运算符,可以使用 pq.push(v[0][0])
重做的代码:
#include <iostream>
using namespace std;
#include <vector>
#include <queue>
int main()
vector<int> *v = new vector<int>;
v -> push_back(1);
//min priority queue
priority_queue<int, vector<int>, greater<int>> pq;
pq.push((*v)[0]);
delete v; // don't forget.
【讨论】:
它会使编译错误消失,但不是解决问题的好方法 - 请参阅其他答案***.com/a/69405441/151019 要回答我会说错误是您在向量上使用 new - 修复该行 @mmmmmm 再看看我的回答。问题出在哪里??我们不要使用指针,因为它们很复杂,对吧?他将不得不在某个时候处理指针,最好从现在开始学习,而不是花费数小时弄清楚如何修复编译.. 这是一个糟糕的借口,不能说明不好的做法。对于 OP 可以了解它们的指针,将会有大量的合法需求。new
ing 标准库容器非常可能不是。我们不要鼓励反模式。
@sweenish 确实对于这个例子来说这是一个不好的做法,但这是另一个话题。发布这个问题的人并没有要求一个好的做法。他问为什么编译失败。以上是关于为啥我们不能在动态向量的情况下使用方括号?的主要内容,如果未能解决你的问题,请参考以下文章