如果我定义一个指向定义[]
运算符的对象的指针,是否有直接从指针访问此运算符的方法?
例如,在下面的代码中,我可以使用指针的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)[]
的替代品。
答案 0 :(得分:35)
您可以执行以下任何操作:
#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)
,即使它的含义略有不同。
答案 1 :(得分:8)
return VecPtr->operator[](0);
......会做的。但实际上,(*VecPtr)[0]
形式看起来更好,不是吗?
答案 2 :(得分:3)
您可以将其用作VecPrt->operator [] ( 0 )
,但我不确定您会发现它不那么模糊。
答案 3 :(得分:2)
(*VecPtr)[0]
完全没问题,但如果您愿意,可以使用at
功能:
VecPtr->at(0);
请注意,如果索引不在范围内,这(与operator[]
不同)将抛出std::out_of_range
异常。
答案 4 :(得分:2)
还有另一种方法,你可以使用对象的引用:
#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
相同,您可以(*p)
替换所有出现的r
。
警告:这只有在不会修改指针(即更改指向的对象)时才有效。
请考虑以下事项:
#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
)。
所以,同样,只有在仍然使用引用的情况下指针不会改变时,这才有效。
这些示例仅因为vector<int> ... = {...};
答案 5 :(得分:1)
值得注意的是,在C ++ 11中,std :: vector有一个成员函数&#39; data&#39;返回指向底层数组(const和非const版本)的指针,允许您编写以下内容:
VecPtr->data()[0];
这可能是
的替代方案VecPtr->at(0);
会产生很小的运行时间开销,但更重要的是它的使用意味着在调用之前你不会检查索引的有效性,这在你的特定例子中是不正确的。
有关详细信息,请参阅std::vector::data。
答案 6 :(得分:-2)
由于范围检查,人们建议您使用->at(0)
。但这是我的建议(以其他观点):
从不使用->at(0)
!它真的很慢。你会牺牲性能只是因为你懒得自己不检查范围吗?如果是这样,你不应该用C ++编程。
我认为(*VecPtr)[0]
没问题。