Разыменование в цикле for - PullRequest
3 голосов
/ 18 марта 2020

Очевидно, у меня было неверное предположение, что разыменование указателя всегда создаст временный объект. Например, в следующем фрагменте кода

vector<string> *vecptr = new vector<string>();
...populate vector...
for(string& str: *vecptr)
{ //do something }

я всегда думал, что * vecptr создаст локальный временный объект и будет неэффективным. Я был склонен к разыменованию в l oop и делал бы что-то вроде

for(vector<string>::iterator str = vecptr->begin(); ....

во избежание разыменования. Я только что узнал, что разыменование не создает временный объект в первом случае, поэтому нет необходимости избегать его. Что такое правило C ++, которое избегает создания временного объекта в таком случае. В обычном случае

string str = *ptr_string;

будет копировать, поскольку * ptr_string является в этом случае значением r? Почему отличается от for для l oop?

1 Ответ

4 голосов
/ 18 марта 2020

, поэтому нет необходимости избегать этого.

Что ж, есть причины избегать косвенного обращения, когда это возможно. Но эта «временная» причина не является такой, поскольку она не соответствует действительности.

Что такое правило C ++, которое позволяет избежать создания временного объекта в таком случае.

Просто нет не является правилом, утверждающим, что будет создан временный объект.

будет копироваться, поскольку * ptr_string в этом случае является rvalue?

*ptr_string является lvalue; не рвалуе. (при условии, что decltype(ptr_string) равно std::string*; это может быть значением для странных перегрузок унарного оператора * для типов классов).

string str = ... будет копировать, потому что это копирование, инициализирующее объект значения.

Почему отличается от for для l oop?

С l oop ничего не отличается. Вы также можете сделать копию с помощью al oop:

for(string  str: *vecptr)
  //      ^ is not a reference: therefore it is a copy of the element

Так же как и без копирования с "обычной" переменной:

string& str = *ptr_string;
  //  ^ is a reference: therefore not a copy

Это также полностью то же самое, даже если вы не перенаправили указатель, а вместо этого использовали другое значение lvalue, например, ссылку или имя переменной.

...