简体   繁体   English

重载运算符 () 而不是 [] 用于索引

[英]Overloading operator () instead of [] for indexing

An old code base I'm refactoring has a rather unorthodox way to access n dimensional vectors by overloading the () operator instead of the [] operator.我正在重构的旧代码库通过重载()运算符而不是[]运算符来访问 n 维向量。

To illustrate, suppose Vec is a class that overloads both operators for indexing purpose of an internal list of doubles.为了说明,假设 Vec 是一个 class ,它重载两个运算符以用于索引内部双精度列表。

Vec v, w;
int index = 651;
double x = v(index);   // they index like this ..
double y = w[index];   // .. instead of like normally..

I can only think of one good reason why you would do this: The operator[] requires an argument of type size_t which may or may not be uint64 depending on the platform.我只能想到一个很好的理由为什么要这样做: operator[]需要一个size_t类型的参数,它可能是也可能不是uint64 ,具体取决于平台。 On the other hand, the index type used in the code is mostly int , which would mean a lot of implicit/explicit type casting when indexing.另一方面,代码中使用的索引类型主要是int ,这意味着在索引时会进行大量的隐式/显式类型转换。 The code is extremely indexing heavy, so I'm quite hesitant to change this.该代码的索引非常繁重,所以我很犹豫要不要更改它。

Does this really makes any sense for todays modern compilers and 64bit platforms?这对于当今的现代编译器和 64 位平台真的有意义吗? I quickly whipped up a test on https://godbolt.org/ You can try it out here here我很快在https://godbolt.org/上进行了测试 你可以在这里试试

I was primarily concerned with the latest x64 gcc and Visual Studio compilers, but the difference is primarily when compiling in x86-64 gcc (11.2).我主要关注最新的 x64 gcc 和 Visual Studio 编译器,但区别主要在于在 x86-64 gcc (11.2) 中编译时。 Gcc adds a cdqe instruction for the () operator, which we know may be less efficient . Gcc 为()运算符添加了一条cdqe指令,我们知道这可能效率较低

Hence I am a bit puzzled.因此我有点疑惑。 Why would one make this choice?为什么会做出这样的选择?

One "problem" with [] is when you have multiple dimensions. []的一个“问题”是当您有多个维度时。 With an array you can do arr[val1][val2] , and arr[val1] will give you an array you can index with [val2] .使用数组你可以做arr[val1][val2] ,并且arr[val1]会给你一个可以用[val2]索引的数组。 With a class type this isn't as simple.对于 class 类型,这并不简单。 There is no [][] operator so the [val1] needs to return an object that [val2] can be applied to.没有[][]运算符,因此[val1]需要返回可以应用[val2]的 object。 This means you need to create another type and provide all the functionality you want.这意味着您需要创建另一种类型并提供您想要的所有功能。 With () , you can do data(val1, val2) and no intermediate object is needed.使用() ,您可以执行data(val1, val2)并且不需要中间 object。

The operator[] requires an argument of type size_t operator[]需要一个size_t类型的参数

This is incorrect.这是不正确的。 operator[] can accept an operand of any type, including non-integral types. operator[]可以接受任何类型的操作数,包括非整数类型。 However, the limitation is that it must be a single argument.但是,限制是它必须是单个参数。 This may change in a future standard, but if your code is old, it is clearly affected.这可能会在未来的标准中改变,但如果你的代码是旧的,它显然会受到影响。

Does this really makes any sense for todays modern compilers and 64bit platforms?这对于当今的现代编译器和 64 位平台真的有意义吗?

Using 32-bit indexes on a 64-bit platform may be beneficial, if you have to store a lot of indexes and don't need the extra range.如果您必须存储大量索引并且不需要额外的范围,则在 64 位平台上使用 32 位索引可能是有益的。 Keeping your data condensed not only saves memory, but may also improve CPU cache hit rate and increase performance.保持数据压缩不仅可以节省 memory,还可以提高 CPU 缓存命中率并提高性能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM