Изменить: Вот лучший код для воспроизведения. Все версии MSV C ниже 19.20 не могут скомпилировать тест.
Эта проблема связана с этим сообщением SO . Я заметил, что мое приложение завершается, когда logi c под inplacer
выдает исключение.
Вот код для воспроизведения:
#include <optional>
struct S{};
S foo() { throw "oh, noes..."; }
template<class F>
struct inplacer
{
F f_;
operator std::invoke_result_t<F&>() { return f_(); }
};
template<class F> inplacer(F) -> inplacer<F>;
int main()
try
{
std::optional<S> v;
v.emplace( inplacer{ []{ return foo(); } } );
return 0;
}
catch(...) { return 1; }
Если я создам это с помощью MSV C v15.9.20 и запускаем - процесс получает std::terminate()
d. Похоже, проблема в _Construct_in_place()
:
template<class _Ty,
class... _Types> inline
void _Construct_in_place(_Ty& _Obj, _Types&&... _Args)
_NOEXCEPT_COND(is_nothrow_constructible_v<_Ty, _Types...>) <----- HERE???
{ // invoke True Placement New to initialize the referenced object with _Args...
::new (const_cast<void *>(static_cast<const volatile void *>(_STD addressof(_Obj))))
_Ty(_STD forward<_Types>(_Args)...);
}
// std::_Construct_in_place<S,inplacer<S <lambda>(void) > >(S & _Obj, inplacer<S <lambda>(void) > && <_Args_0>)
Похоже, что is_nothrow_constructible_v<S, inplacer<...>>
дает ложное срабатывание, что приводит к объявлению noexcept
, которое, в свою очередь, убивает мое приложение, когда выдает базовый код.
PS G CC и Clang вроде работают нормально.