Являются ли временные объекты в C ++ const действительно? - PullRequest
4 голосов
/ 15 января 2011

Я всегда считал, что временные объекты в C ++ автоматически рассматриваются компилятором как const.Но недавно я обнаружил, что следующий пример кода:

function_returning_object().some_non_const_method();

действителен для компилятора C ++.И это заставляет меня задуматься - действительно ли временные объекты в C ++ const?Если да, то почему приведенный выше код считается корректным компилятором?

Ответы [ 6 ]

6 голосов
/ 15 января 2011

Нет, это не так. Нет, если вы не объявите тип возвращаемого значения как const.

5 голосов
/ 15 января 2011

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

Разрешить неОперации -const для временного особенно полезны, когда вы хотите вызвать «swap» для него с локальной переменной.

std::vector<T> local;
method_that_returns_a_vector().swap( local );

До появления семантики перемещения это считалось наиболее эффективным способом возвратабольшой набор данных и получить его без копирования всех данных.

5 голосов
/ 15 января 2011

Это зависит.

int f();
const int g();

class C { };
C x();
const C y();

В случае как f(), так и g(), возвращаемое значение не является константным, поскольку нет определенных с константой значений r не-классового типа.const в типе возврата g() совершенно бесполезен (на самом деле, он хуже, чем бесполезен, поскольку в редких случаях может вызвать проблемы с созданием шаблона).

В случае x()возвращаемое значение не является константным (потому что оно не является константным).В случае y() возвращаемое значение является константным (поскольку тип возвращаемого значения является константным).Квалификатор const здесь (или его отсутствие) имеет смысл, поскольку тип возвращаемого значения является типом класса.

2 голосов
/ 15 января 2011

Временные объекты не являются константными, но они могут связываться только с константными ссылками.Нетрудно показать, что временные привязки к неконстантным ссылочным значениям будут полезны практически во всех сценариях.Вы также не можете взять адрес временного, даже если вы можете связать ссылку на него, и в отношении временных файлов в C ++ 03 происходит ряд других очень глупых вещей.Просто будьте рады, что C ++ 0x скоро будет здесь ... надеюсь.

2 голосов
/ 15 января 2011

Временные объекты могут быть постоянными, но они не должны быть такими.

((string const)"hello").append(" world"); // error!

Позволяет разные вещи.Рассмотрим

struct bitref {
  int index;
  bitref &operator=(bool value); // non-const!
};

struct bitset {
  int flags;
  // returns a bitref temporary that's associated with the bit
  // at index 'index'. 
  bitref operator[](int index); 
  // ...
};

Вы можете сделать

bitset b;
b[1] = true; // change second bit to 1

Вот что делает шаблон std::bitset<>

0 голосов
/ 15 января 2011

Все зависит от типа возвращаемого значения функции.

//Temporary objects: nameless objects that are only usable in current statement
Object function();           //Return a temporary object by value (using copy constructor)
const Object function();     //Return a const temp object by value

//references, return a reference to an object existing somewhere else in memory
Object & function();         //Return an object reference, non-const behaves as any other non-const
const Object & functon();    //Return const obj reference, behaves as any other const
...