哪个向量地址更安全?
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 上 & 或 [] 的运算符重载对更改运算符优先级的优先级有任何影响吗? 如果向量(或两者)在获得地址后调整大小怎么办?【问题讨论】:
有运算符优先级规则。这与安全无关,而是正确性 第二个是“更安全”,因为如果你赶时间,你不能把它误解为(&input)[j]
。否则,它们是等价的。
在函数中使用指针必须类似于(*parameter)[k]
,但它看起来当然不同,我也关心*parameter[k]
。
【参考方案1】:
operator[]
has higher precedence then operator&
(后缀运算符优先级最高),所以这里先求值,不需要括号。 &input[j]
和 &(input[j])
这里没有区别。
替代的更简单的语法:
auto selectedVectorPtr = input.data() + j;
这里也不需要std::addressof
。
【讨论】:
()
是创建一个临时对象还是直接取消引用数组?
@huseyintugrulbuyukisik ()
不会创建临时对象。
我不明白为什么替代方法应该更简单。对我来说,&input[j]
明确表示:“获取j
th 元素的地址”。 input.data() + j
要求我首先读取成员名称,回想它返回一个指针,识别 + j
对其调用指针运算,然后推断结果将是 j
th 元素的地址... (顺便说一句。在 C 代码中,我什至更喜欢 &ptr[i]
而不是 ptr + i
。)
@cmaster 我更喜欢pointer + index
。但是感谢您分享您的心理过程。
为什么更喜欢pointer + index
?你的心理过程是什么?【参考方案2】:
operator precedence 规定在前导 &
之前评估 []
。因此,这两种表达方式没有区别。
当您想知道 sn-ps 的安全影响时,&input[j]
需要考虑两个问题(不管外括号如何):
std::vector::at
而不是 std::vector::operator[]
并将其包装到 try
-catch
块中。
如果要取T
的地址,这是先验未知的,operator &
可以重载为T
。虽然这首先是邪恶的,但您可以使用std::addressof
来减少这种可能性。请注意,在您的情况下这不是必需的,因为您使用的是 std::vector
实例的地址。
【讨论】:
你的意思是如果有人使用类而不是浮点数或双精度数,它会导致操作优先级发生变化,因此运算符 & 优先? 不,您不能通过重载来更改运算符优先级。但是您可以通过为用户定义的类型重载operator &
来更改它的含义。
恕我直言,超载operator &
的人得到的正是他们应得的……所以,没有必要使用std::address_of<>
;-) 很好地提到了这些问题,为此 +1!【参考方案3】:
&input[j]
和&(input[j])
不会有任何区别。这是因为operator[]
的优先级高于operator&
。
所以在这两种情况下,它都会评估为&(input[j])
【讨论】:
以上是关于哪个向量地址更安全?的主要内容,如果未能解决你的问题,请参考以下文章
基本 STL:向量列表或列表向量,在这种特殊情况下哪个更好?