Некоторые кодирующие снобы смотрят на них как на простое прославленное глобальное. Точно так же, как многие люди ненавидят инструкцию goto , есть другие, которые ненавидят идею когда-либо использовать глобальный . Я видел, как несколько разработчиков идут на необычные длины, чтобы избежать global , потому что они считали использование одного в качестве допуска отказа. Странно, но верно.
На практике шаблон Singleton - это всего лишь метод программирования, который является полезной частью вашего инструментария понятий. Время от времени вы можете обнаружить, что это идеальное решение, и поэтому используйте его. Но использование этого только для того, чтобы вы могли похвастаться использованием шаблона дизайна , так же глупо, как и отказаться от использования, потому что это всего лишь глобальный .
Просто прочитайте ответ Коломбо .
Это ошибка gcc. Соответствующее правило находится в [class.temporary] :
Существует два контекста, в которых временные файлы уничтожаются в другой точке, чем конец полного выражения. [...]
Второй контекст - это когда ссылка привязана к временному. Временное, к которому привязана ссылка, или временное, являющееся полным объектом подобъекта, к которому привязана ссылка, сохраняется для времени жизни ссылки, за исключением: - временного объекта, связанного с опорным параметром в вызове функции (5.2. 2) сохраняется до завершения полного выражения, содержащего вызов. - срок жизни временной привязки к возвращаемому значению в операторе return функции (6.6.3) не продлевается; временное уничтожается в конце полного выражения в операторе return. - Временная привязка к ссылке в [new] инициализаторе (5.3.4) сохраняется до завершения полного выражения, содержащего новый инициализатор .
Мы привязываем ссылку на подобъект временного, поэтому временное должно сохраняться для срока службы ссылки. Ни одно из этих трех исключений из этого правила не применяется здесь.
Я бы утвердил ошибку в g ++, потому что, цитируя draft N3242 , §12.2 / 5:
Второй контекст - это когда ссылка привязана к временный. Временное, к которому привязана ссылка, или временное, являющееся полным объектом подобъекта, к которому привязана ссылка, сохраняется для времени жизни ссылки, за исключением:
. Таким образом, его время жизни должно быть расширенный, за исключением случаев, когда:
Временная привязка к ссылочному элементу в ctor-initializer конструктора [..]
Временная привязка к эталонному параметру в вызове функции [..]
Время жизни временной привязки к возвращаемому значению в операторе return функции [..]
Временная привязка к ссылке в
new-initializer
[. .]Наш случай не соответствует ни одному из этих исключений, поэтому он должен следовать правилу. Я бы сказал, что g ++ здесь не так.
Затем, в отношении котировки aschepler, поднятой из того же проекта §8.5.3 / 5 (выделение мое):
A ссылка на тип « cv1
T1
» инициализируется выражением типа « cv2T2
» следующим образом:
- Если ссылка является ссылкой на lvalue и выражением инициализатора a. является lvalue (но не является битовым полем), а « cv1
T1
» является ссылочным-совместимым с « cv2T2
» или b. имеет тип класса ... тогда ...- В противном случае ссылка должна быть ссылкой lvalue на нелетучий тип const (то есть cv1 должна быть
const
), или ссылка должна быть ссылкой rvalue. а. Если выражение инициализатора i. является значением xvalue, классом prvalue, значением prvalue или значением функции lvalue и " cv1T1
" является ссылочным-совместимым с " cv2T2
" или ii. имеет тип класса ... тогда ссылка привязана к значению выражения инициализатора в первом случае .... b. В противном случае временный тип « cv1T1
» создается и инициализируется из выражения инициализатора, используя правила для неосновной копии-инициализации (8.5). Ссылка затем привязана к временному.Глядя на то, что такое xvalue, на этот раз ссылаясь на http://en.cppreference.com/w/cpp / language / value_category ...
Выражение xvalue ("expying value") [..]
a.m
, член объекта выражение, где a - значение r, а m - нестатический элемент данных не ссылочного типа;... выражение
center().x
должно быть значением x, поэтому случай 2a из Применяется §8.5.3 / 5 (а не копия). Я останусь с моим предложением: g ++ ошибается.
xvalue
, указано, что вызов функции, возвращающий неосновную ссылку, является prvalue
. Таким образом, center()
является prvalue
и, я полагаю, также center().x
является prvalue
, а не xvalue
. По-видимому, намерение состоит в том, чтобы отодвинуть xvalue
только на случаи перемещения-строительства ...
– 6502
13 March 2016 в 08:37
center()
является prvalue, который является rvalue. Кроме того, x
является нестационарным членом данных. Таким образом, приведенная мной часть относится. Возможно, это помогает: двойной, возвращаемый с 2.0 + 2.0
, является временным, но у него нет «идентификатора»; это просто ценность. center().x
также является временным двойником, но он имеет i> идентификатор, это один из двух элементов данных из P2d
.
– Daniel Jour
13 March 2016 в 08:49
center()
является AFAIK aprvalue
, и я предполагаю, что подобъект aprvalue
также являетсяprvalue
. Учитывая, что в этом примере нет «класса prvalue», мне кажется, что формулировка в 8.5.3 диктует создание временногоdouble
и привязки к нему вместо привязки к подобъекту-члену. – 6502 13 March 2016 в 08:34center().x
являетсяxvalue
? В определении сказано: «X-значение является результатом определенных видов выражений, содержащих ссылки rvalue». Где ссылка rvalue в этом случае? – 6502 13 March 2016 в 11:29