Могу ли я получить доступ к членам временных объектов?
Могу ли я получить доступ к члену объекта, если я создаю временный объект с помощью 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), все семантические ограничения должны соблюдаться, как если бы временный объект был создан, а затем уничтожен.