从指针访问[]操作符

Accessing the [] operator from a pointer

本文关键字:操作符 访问 指针      更新时间:2023-10-16

如果我定义一个指向定义了[]操作符的对象的指针,是否有从指针直接访问该操作符的方法?

例如,在下面的代码中,我可以使用指针的->操作符直接访问Vec的成员函数(如empty()),但如果我想访问[]操作符,我需要首先获得对对象的引用,然后调用操作符。

#include <vector>
int main(int argc, char *argv[])
{
    std::vector<int> Vec(1,1);
    std::vector<int>* VecPtr = &Vec;
if(!VecPtr->empty())      // this is fine
    return (*VecPtr)[0]; // is there some sort of ->[] operator I could use?
return 0;
}

我很可能错了,但看起来做(*VecPtr).empty()比做VecPtr->empty()效率低。这就是为什么我在寻找(*VecPtr)[]的替代品。

您可以做以下任何事情:

#include <vector>
int main () {
  std::vector<int> v(1,1);
  std::vector<int>* p = &v;
  p->operator[](0);
  (*p)[0];
  p[0][0];
}

顺便说一下,对于std::vector的特殊情况,您也可以选择:p->at(0),尽管它的含义略有不同。

return VecPtr->operator[](0);

…会有效果的。但实际上,(*VecPtr)[0]形式看起来更好,不是吗?

(*VecPtr)[0]是完全可以的,但如果您想使用at函数:

VecPtr->at(0);

请记住,如果索引不在operator[]范围内,则会抛出std::out_of_range异常。

还有一种方法,你可以使用对象的引用:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v = {7};
    vector<int> *p = &v;
    // Reference to the vector
    vector<int> &r = *p;
    cout << (*p)[0] << 'n'; // Prints 7
    cout <<    r[0] << 'n'; // Prints 7
    return 0;
}

这样,rv是一样的,你可以用r替换所有出现的(*p)

警告:这只会在不修改指针(即改变它指向的对象)的情况下起作用。

考虑以下内容:

#include <iostream>
#include <vector>
using namespace std;
int main()
{
    vector<int> v = {7};
    vector<int> *p = &v;
    // Reference to the vector
    vector<int> &r = *p;
    cout << (*p)[0] << 'n'; // Prints 7
    cout <<    r[0] << 'n'; // Prints 7
    // Caveat: When you change p, r is still the old *p (i.e. v)
    vector<int> u = {3};
    p = &u; // Doesn't change who r references
    //r = u; // Wrong, see below why
    cout << (*p)[0] << 'n'; // Prints 3
    cout <<    r[0] << 'n'; // Prints 7
    return 0;
}

r = u;是错误的,因为你不能改变引用:这将修改由r (v)引用的向量。而不是引用另一个向量(u)。所以,同样,这只适用于指针在使用引用时不会改变的情况。

示例需要c++ 11只是因为vector<int> ... = {...};

您可以使用它作为VecPrt->operator [] ( 0 ),但我不确定您会发现它不那么晦涩

值得注意的是,在c++ 11中std::vector有一个成员函数'data',它返回一个指向底层数组的指针(包括const和非const版本),允许您编写以下内容:

VecPtr->data()[0];

这可能是

的替代选项
VecPtr->at(0);

会产生很小的运行时开销,但更重要的是,它的使用意味着您在调用索引之前没有检查索引的有效性,这在您的特定示例中不是这样的。

参见std::vector::data。

由于范围检查,人们建议您使用->at(0)。但这是我的建议(从其他角度):

NEVER使用->at(0) !它真的很慢。你会因为懒得自己检查范围而牺牲性能吗?如果是这样,你就不应该用c++编程。

我认为(*VecPtr)[0]是可以的。