简体   繁体   中英

Why don't I need to use the dereference operator with a map's .at() method?

In C++, I've always learned to use the address-of and dereference operators like so:

char s = 's';
char *t = &s;

t = 't'; // would be a compile error, because t must first be dereferenced
*t = 't'; // this works

Then why does this work?

map<string, vector<char>> letters = {
    {"first", {'a', 'b', 'c'}},
    {"middle", {'l', 'm', 'n'}},
    {"last", {'x', 'y', 'z'}}
};
vector<char> section = letters.at("first");

It's my understanding that .at() returns a reference to the mapped element at the specified key. Why can't that last line be this:

vector<char> *section = letters.at("first"); // this doesn't work!

I can then go on to use section , accessing its methods with the . operator instead of the -> operator, even though, according to cplusplus.com it returns a reference:

char first_letter = section.at(0); // not section->at(0);

What's going on here? Am I actually getting a reference to the vector inside the map ? If so, why don't I need to use the arrow operator to dereference the returned element variable so that its method can be invoked?

In C++ a reference is, in short, an alias for an object, and is different from a pointer.
By dereferencing a pointer you're accessing the pointed-to object (or reference).
With a reference you use the . operator to access members, with a pointer you use the -> operator.

map<string, vector<char>>::at() returns a vector<char> & (a reference, which in practice looks to the programmer as an actual object, ie as if it was a vector<char> ). That's not a vector<char> * (a pointer to vector<char> object).

You're confused about references and pointers. The common use of the word 'dereference' doesn't help things for you either, as you don't actually have to dereference references. ;-(

You can think of a reference as being like a pointer, but with added syntactic sugar that hides it's underlying representation.

So if you have a reference like int &iref = i; you can use iref just like you'd use i .

  iref = 42;
  iref += 100;

But, if you have a pointer, you must use the dereference operator * .

  *iref = 42;
  *iref += 100;

at() returns a reference, not a pointer:

vector<char> &section = letters.at("first");
char first_letter = section.at(0); 

You cannot assign a reference to a pointer, but you can use the & address operator on a reference to get a pointer to the item being referenced:

vector<char> *section = &(letters.at("first"));
char first_letter = section->at(0); 

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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