Вы разыменовываете const optional<datatype>
, вы используете const value_type & optional::operator*() const
, а не value_type & optional::operator*()
.
Свободное определение функции смотрит только на имена, объявленные перед ним. Это одна из причин наличия в заголовках объявлений функций. В случае функции-члена определения членов видят все объявления членов.
foo(dataType& bar)
не является допустимой перегрузкой. Если вы не объявили foo(const dataType& bar)
перед определением foo(const optional<dataType>& bar)
, единственной жизнеспособной перегрузкой будет foo(const optional<dataType>& bar)
, которая создает временную опцию. Он выводит U
как const dataType &
, а const dataType & &&
равно свернуто до const dataType &