Могу ли я получить доступ к членам временных объектов?

Могу ли я получить доступ к члену объекта, если я создаю временный объект с помощью class-type-name(parameters).member и предположить, что конструктор сделан?

Рассмотрим следующий пример:

struct A
{
  enum status 
    { ERROR = -1, SUCCESS } state;
  A (int a) 
    : state(a > 0 ? SUCCESS : ERROR)
  {
    // do some stuff here
    // may change state
  }
};

int main (void)
{
  // Is this guaranteed to work?
  A::status S(A(5).state);
}

Требуется ли конструктор A, как только я получу доступ? state?

1 ответ

Решение

Да, стандарт требует, чтобы реализация выполняла все вычисления и побочные эффекты конструктора A до доступа state,


Ссылка:

Выражение X(Y).Z является выражением Postfix согласно 5.2.5/1 C++11:

Постфиксное выражение, за которым следует точка. или стрелка ->, за которой необязательно следует ключевое слово template (14.2), а за ним следует id-выражение, является выражением постфикса.

Выражение X(Y) оценивается в соответствии с тем же пунктом:

Выражение постфикса перед точкой или стрелкой оценивается. 64

64: Если вычисляется выражение доступа к члену класса, оценка подвыражения происходит, даже если в результате нет необходимости определять значение всего выражения постфикса, например, если id-выражение обозначает статический член.

Вот где применяется 1.9/14:

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

Поэтому расчеты и побочные эффекты X(Y) выполняются, как только вычисляется оператор точки.

Однако это выражение генерирует полностью построенный объект X согласно 5.2.3 / 1:

[...] выражение T(x1, x2, ...) по сути эквивалентен декларации T t(x1, x2, ...); для какой-то придуманной временной переменной t с результатом, являющимся значением t в качестве стоимости.

и 12,2/3:

Когда реализация вводит временный объект класса, который имеет нетривиальный конструктор (12.1, 12.8), он должен гарантировать, что конструктор вызывается для временного объекта. [...] Временные объекты уничтожаются как последний шаг в оценке полного выражения (1.9), которое (лексически) содержит точку, где они были созданы.

Стандарт требует, чтобы программа вела себя так, даже если точное создание временного объекта не было выполнено (12.2/1):

Даже если создание временного объекта не оценено (пункт 5) или иным образом исключено (12.8), все семантические ограничения должны соблюдаться, как если бы временный объект был создан, а затем уничтожен.

Другие вопросы по тегам