从指针访问[]操作符
Accessing the [] operator from a pointer
如果我定义一个指向定义了[]
操作符的对象的指针,是否有从指针直接访问该操作符的方法?
例如,在下面的代码中,我可以使用指针的->
操作符直接访问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;
}
这样,r
和v
是一样的,你可以用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]
是可以的。
- 通过方法访问结构
- 使用不带参数的函数访问结构元素
- 下标操作符重载以访问私有数组
- 通过自增操作符访问类成员
- 从结构体访问数据时,操作符重载到哪里去了?
- 从指针访问[]操作符
- 获取/释放通过[]操作符访问的原子变量的语义
- 如何创建一个std::map的常数值,它仍然可以被[]操作符访问
- c++为什么不使用星号操作符访问动态数组
- 在2D数组中通过重载数组下标操作符进行访问
- 通过结构和重载操作符包装CUDA共享内存定义和访问
- TBB concurrent_hash_map操作符[]或类似的访问
- 访问由std::shared_ptr封装的类的操作符重载
- 如何在重载操作符后访问标准的*此行为
- 通过std::unique_ptr使用std::map访问操作符[]的正确语法
- 从模板化的类赋值操作符访问私有成员变量
- 关于模板中随机访问迭代器的操作符+重载的问题
- 为什么c++中的成员函数在对象名后用点操作符访问?
- 在c++中从父命名空间访问隐藏操作符
- 如何在操作符[]上分离get和set访问