看起来 is_nothrow_constructible_v() 在 MSVC 中被破坏了,我错了吗?

Posted

技术标签:

【中文标题】看起来 is_nothrow_constructible_v() 在 MSVC 中被破坏了,我错了吗?【英文标题】:Looks like is_nothrow_constructible_v() is broken in MSVC, am I wrong? 【发布时间】:2020-07-10 19:52:38 【问题描述】:

编辑: Here is 更好的代码重现。所有低于 19.20 的 MSVC 版本都无法编译测试。


此问题与this SO post 有关。我注意到当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; 

如果我使用 MSVC 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&lt;S, inplacer&lt;...&gt;&gt; 产生误报,导致noexcept 声明,当底层代码抛出时,这反过来会杀死我的应用程序。

附: GCC 和 Clang 似乎工作正常。

【问题讨论】:

【参考方案1】:

这是一个known bug。在 msvc v19.16 中修复。

【讨论】:

以上是关于看起来 is_nothrow_constructible_v() 在 MSVC 中被破坏了,我错了吗?的主要内容,如果未能解决你的问题,请参考以下文章

GridLayout 在真实设备上看起来很奇怪,在模拟器上看起来很完美

Swift List 看起来太大了

OpenGL 轴看起来不同

为啥这个组合框看起来像这样?

有啥办法可以让选择看起来很普通吗?

《你只是看起来很努力》--读书笔记