Если присваивать унинитиализированному факультативно<T&>
эффект состоит в том, чтобы связать (впервые) с объектом. Очевидно, нет другого выбора.
int x = 1 ;
int& rx = x ;
optional<int&> ora ;
optional<int&> orb(x) ;
ora = orb ;
*ora = 2 ;
assert(x==2);
Если вы присваиваете голую ссылку на C++, задание направляется на упомянутый объект; его значение изменяется, но ссылка никогда не отступает.
int a = 1 ;
int& ra = a ;
int b = 2 ;
int& rb = b ;
ra = rb ;
assert(a==b);
b = 3 ;
assert(ra!=b);
Теперь, если вы присваиваете иализированному факультативно<T&>
, эффект заключается в переведении на новый объект вместо присвоения рефери. Это не похоже на голые ссылки на C++.
int a = 1 ;
int b = 2 ;
int& ra = a ;
int& rb = b ;
optional<int&> ora(ra) ;
optional<int&> orb(rb) ;
ora = orb ;
*ora = 3 ;
assert(a==1);
assert(b==3);
Была выбрана обязательная семантика для присвоения инициализированного (факультативно)
ссылки для обеспечения постоянства среди состояний инициализации даже за счет отсутствия согласованности с семантикой ссылок на C++. Верно, что опционально<U>
стремится вести себя как можно больше, чем U
делает всякий раз, когда он инициализируется; но в случае, когда U
T&
, это приводит к непоследовательному поведению w.r.t к состоянию инициализации.
Представьте себе факультативно<T&>
передаточное присвоение исходному объекту (таким образом, изменение исходного значения объекта, но не переобязательная), и рассмотрим следующий код:
optional<int&> a = get();
int x = 1 ;
int& rx = x ;
optional<int&> b(rx);
a = b ;
Что делает задание?
Если a
является унинициализированным, ответ очевиден: он связывается с x
(мы теперь имеем другую ссылку на x
). Но что, если a
уже первоначализировано? это изменило бы значение исходного объекта (что бы это ни было); что несовместимо с другим возможным случаем.
Если Опционно<T&>
назначит точно так же, как T&
, вы никогда не сможете использовать задание Опциона без явного обращения с предыдущим инициализационным состоянием, если ваш код не сможет функционировать после назначения, a
использует тот же объект, что и b
.
То есть вам придется дискриминировать, чтобы быть последовательным.
Если в вашем коде перевязка с другим объектом не является вариантом, то очень вероятно, что связывание в первый раз тоже не является. В таком случае уступка в унинитиализированную факультативно<T&>
запрещается. Вполне возможно, что в таком сценарии это предварительное условие, что значение l необходимо уже инициализировать. Если это не так, то связывание в первый раз нормально, в то время как перевязка не является тем, что ИМО очень маловероятно. В таком сценарии вы можете назначить само значение напрямую, как:
assert(!!opt);
*opt=value;