哪个向量地址更安全?

Posted

技术标签:

【中文标题】哪个向量地址更安全?【英文标题】:Which vector address is safer? 【发布时间】:2018-09-24 11:39:08 【问题描述】:

假设一个函数需要一个指向类型为 T 的向量的指针,但是当我只有一个类型为 T 的向量的向量时(类型不保证是 POD),是这样的

std::vector<std::vector<T>> input;
auto selectedVectorPtr=&input[j];

比这更安全

std::vector<std::vector<T>> input;
auto selectedVectorPtr=&(input[j]);

还假设输入的范围在以selectedVectorPtr 作为参数的函数之前不会结束。

我的担忧(/误解)是:

() 是否创建任何临时对象?那么取地址不好吗? 类型 T 上 & 或 [] 的运算符重载对更改运算符优先级的优先级有任何影响吗? 如果向量(或两者)在获得地址后调整大小怎么办?

【问题讨论】:

有运算符优先级规则。这与安全无关,而是正确性 第二个是“更安全”,因为如果你赶时间,你不能把它误解为(&amp;input)[j]。否则,它们是等价的。 在函数中使用指针必须类似于(*parameter)[k],但它看起来当然不同,我也关心*parameter[k] 【参考方案1】:

operator[] has higher precedence then operator&amp;(后缀运算符优先级最高),所以这里先求值,不需要括号。 &amp;input[j]&amp;(input[j]) 这里没有区别。


替代的更简单的语法:

auto selectedVectorPtr = input.data() + j;

这里也不需要std::addressof

【讨论】:

() 是创建一个临时对象还是直接取消引用数组? @huseyintugrulbuyukisik () 不会创建临时对象。 我不明白为什么替代方法应该更简单。对我来说,&amp;input[j] 明确表示:“获取jth 元素的地址”。 input.data() + j 要求我首先读取成员名称,回想它返回一个指针,识别 + j 对其调用指针运算,然后推断结果将是 jth 元素的地址... (顺便说一句。在 C 代码中,我什至更喜欢 &amp;ptr[i] 而不是 ptr + i。) @cmaster 我更喜欢pointer + index。但是感谢您分享您的心理过程。 为什么更喜欢pointer + index?你的心理过程是什么?【参考方案2】:

operator precedence 规定在前导 &amp; 之前评估 []。因此,这两种表达方式没有区别。

当您想知道 sn-ps 的安全影响时,&amp;input[j] 需要考虑两个问题(不管外括号如何):

索引可能超出范围,导致未定义的行为。您可能想要使用(可能会抛出但更安全)std::vector::at 而不是 std::vector::operator[] 并将其包装到 try-catch 块中。 如果要取T 的地址,这是先验未知的,operator &amp; 可以重载为T。虽然这首先是邪恶的,但您可以使用std::addressof 来减少这种可能性。请注意,在您的情况下这不是必需的,因为您使用的是 std::vector 实例的地址。

【讨论】:

你的意思是如果有人使用类而不是浮点数或双精度数,它会导致操作优先级发生变化,因此运算符 & 优先? 不,您不能通过重载来更改运算符优先级。但是您可以通过为用户定义的类型重载operator &amp; 来更改它的含义。 恕我直言,超载operator &amp; 的人得到的正是他们应得的……所以,没有必要使用std::address_of&lt;&gt; ;-) 很好地提到了这些问题,为此 +1!【参考方案3】:

&amp;input[j]&amp;(input[j]) 不会有任何区别。这是因为operator[] 的优先级高于operator&amp;

所以在这两种情况下,它都会评估为&amp;(input[j])

【讨论】:

以上是关于哪个向量地址更安全?的主要内容,如果未能解决你的问题,请参考以下文章

将向量地址转换为本机指针是不是安全?

堆栈/堆中的向量元素?长输入,C++

C ++中不同向量之间没有线程安全?

基本 STL:向量列表或列表向量,在这种特殊情况下哪个更好?

支持向量机用malt lab做好,还是R语言还是python好?

机器学习之四:支持向量机推导