Accessing the [] operator from a pointer
Solution 1
You could do any of the following:
#include <vector>
int main () {
std::vector<int> v(1,1);
std::vector<int>* p = &v;
p->operator[](0);
(*p)[0];
p[0][0];
}
By the way, in the particular case of std::vector
, you might also choose: p->at(0)
, even though it has a slightly different meaning.
Solution 2
return VecPtr->operator[](0);
...will do the trick. But really, the (*VecPtr)[0]
form looks nicer, doesn't it?
Solution 3
There's another way, you can use a reference to the object:
#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;
}
This way, r
is the same as v
and you can substitute all occurrences of (*p)
by r
.
Caveat: This will only work if you won't modify the pointer (i.e. change which object it points to).
Consider the following:
#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;
is wrong because you can't change references:
This will modify the vector referenced by r
(v
)
instead of referencing another vector (u
).
So, again, this only works if the pointer won't change while still using the reference.
The examples need C++11 only because of vector<int> ... = {...};
Solution 4
(*VecPtr)[0]
is perfectly OK, but you can use the at
function if you want:
VecPtr->at(0);
Keep in mind that this (unlike operator[]
) will throw an std::out_of_range
exception if the index is not in range.
Solution 5
You can use it as VecPrt->operator [] ( 0 )
, but I'm not sure you'll find it less obscure.
Malabarba
I: am the author of Endless Parentheses; help manage and develop CIDER, the most widely used Clojure IDE; help develop GNU Emacs when I have time; author and manage a number of open source projects, among which: Paradox: Modernized Package Menu for Emacs. sx.el: Full-feature Emacs client for StackOverflow, Super User, and the entire Stack Exchange network. aggressive-indent-mode: Minor mode that keeps your code permanently indented. smart-mode-line: A powerful and beautiful mode-line for Emacs. The Bug-Hunter: Hunt down errors in elisp files. names: A namespace system for elisp.
Updated on July 09, 2022Comments
-
Malabarba almost 2 years
If I define a pointer to an object that defines the
[]
operator, is there a direct way to access this operator from a pointer?For example, in the following code I can directly access
Vec
's member functions (such asempty()
) by using the pointer's->
operator, but if I want to access the[]
operator I need to first get a reference to the object and then call the operator.#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; }
I might very well be wrong, but it looks like doing
(*VecPtr).empty()
is less efficient than doingVecPtr->empty()
. Which is why I was looking for an alternative to(*VecPtr)[]
.-
matth over 12 yearsWhy do you want to avoid
(*VecPtr)[0]
? -
Malabarba over 12 years@Rob Edited with a reason. My assumption might be wrong, but it's why I asked.
-
UncleBens over 12 years
(*VecPtr).empty()
andVecPtr->empty()
are exactly the same thing (unless VecPtr is something that overloadsoperator*
andoperator->
with conflicting meaning. -
matth over 12 yearsIf
VecPtr
is a pointer type, then(*VecPtr).XXX
is, by definition, equivalent toVecPtr->XXX
. There is no loss of efficiency. IfVecPtr
is a non-pointer type that implementsoperator*
andoperator[]
, then you'll have to examine them to see which is more efficient (they are probably the same). -
Kerrek SB over 12 yearsHow is this question getting upvoted?? It is based on one of the most ill-informed and under-researched premises and hardly of value to others.
-
-
Nick over 6 yearswhy at(0) is slow?
-
Theko Lekena about 6 yearsThat last one there is interesting, could you explain what is happening there under the hood? Is that first [0] referring to the "first element" pointed to by the pointer? Similar to how a vector reference is a pointer to the beginning to an array?
-
M.M over 5 years
r = u;
is fine and it will do assignment between the two vectors ; this has nothing to do withp
-
KinGamer over 5 yearsAnd this is what I mean by "wrong". Quoting myself, "you can substitute all occurrences of
(*p)
byr
", but "This will only work if you won't modify the pointer", because there's no way to changer
as you would change the value of*p
.r = u;
"will modify the vector referenced byr
instead of referencing another vector" -- it won't have the intended effect. -
M.M over 5 years
r = u;
will have the same effect whether or not you later modify the pointer -
KinGamer over 5 yearsYes, but I don't get why you're saying that. Again, by "wrong" I mean it doesn't do what
p = ...
would do. And I'm talking about substituting all ocurrences of*p
byr
. But if in your code you havep = ...
, replacingp = ...
byr = ...
is wrong. -
LeonTheProfessional almost 4 years@ThekoLekena exactly, for pointers to complete-types T, the [] operator is defined to access the ith element of the array (by calculating sizeof(T) * i). Of course, since in this case we have a pointer to one vector, having anything else than [0] would be undefined behaviour. edit: i wouldn't choose the last one though, as i find it less idiomatic.
-
Theko Lekena almost 4 years@ancientchild agreed, the last one should not be used as normal practice.