https://gcc.gnu.org/bugzilla/show_bug.cgi?id=79118
--- Comment #4 from Marek Polacek <mpolacek at gcc dot gnu.org> --- Somewhat reduced: namespace std { template <typename _Tp, _Tp __v> struct integral_constant { static constexpr _Tp value = __v; }; template <bool, typename, typename> struct conditional; template <typename...> struct __and_; template <typename _B1, typename _B2> struct __and_<_B1, _B2> : conditional<1, _B2, _B1>::type {}; template <typename _Tp> struct is_trivially_destructible : __and_<_Tp, integral_constant<bool, __has_trivial_destructor(_Tp)>> {}; template <bool, typename _Iftrue, typename> struct conditional { typedef _Iftrue type; }; template <typename> void forward(); } namespace detail { template <class, class, class> class value_storage_impl_trivial { public: static constexpr bool is_referenceable = false; typedef int value_type; struct { char _value_raw; char type : 2; }; constexpr value_storage_impl_trivial(value_type) : _value_raw() {} }; template <class, class, class> class value_storage_impl_nontrivial; template <class, class, class _exception_type> constexpr bool can_have_trivial_destructor = std::is_trivially_destructible<_exception_type>::value; } template <class _value_type, class _error_type, class _exception_type> class value_storage : public std::conditional< detail::can_have_trivial_destructor<_value_type, _error_type, _exception_type>, detail::value_storage_impl_trivial<bool, void, void>, detail::value_storage_impl_nontrivial<bool, void, void>>::type { using base = typename std::conditional< detail::can_have_trivial_destructor<_value_type, _error_type, _exception_type>, detail::value_storage_impl_trivial<_value_type, _error_type, _exception_type>, detail::value_storage_impl_nontrivial<_value_type, _error_type, _exception_type>>::type; public: using typename base::value_type; constexpr value_storage(value_type v) : base(v) {} }; template <class implementation_policy> class basic_monad : public implementation_policy::base { public: typedef typename implementation_policy::value_type value_type; constexpr basic_monad(value_type v) : implementation_policy::base(v) {} }; namespace detail { template <class _implementation_policy> struct basic_monad_storage { typedef _implementation_policy implementation_policy; typedef value_storage<typename implementation_policy::value_type, typename implementation_policy::error_type, typename implementation_policy::exception_type> value_storage_type; value_storage_type _storage; typedef typename implementation_policy::value_type value_type; constexpr basic_monad_storage(value_type v) : _storage(v) {} constexpr bool is_ready() { return _storage.type; } }; template <class monad_storage, class value_type> struct option_policy_base : monad_storage { template <class... Args> constexpr option_policy_base(Args...) : monad_storage(std::forward<Args>...) {} constexpr void _pre_get_value() { monad_storage::is_ready(); } using const_rvalue_type = typename std::conditional< monad_storage::value_storage_type::is_referenceable, value_type, value_type>::type; constexpr const_rvalue_type get() { _pre_get_value(); } }; template <typename> struct A { typedef bool value_type; typedef void error_type; typedef void exception_type; typedef option_policy_base<basic_monad_storage<A>, value_type> base; }; } template <typename R> using option = basic_monad<detail::A<R>>; void boostlite_auto_test_case5() { option<bool>(false).get() == false; }