注意:您的代码有几个问题。在 C++14 中,如果替换operator delete(void*)
那么你还必须更换operator delete(void*, std::size)t)
。您可以使用功能测试宏来查看编译器是否需要:
void operator delete( void *p ) {
free( p );
}
#if __cpp_sized_deallocation
// Also define sized-deallocation function:
void operator delete( void *p, std::size_t ) {
free( p );
}
#endif
其次正确的 printf 格式说明符size_t
is zu
not u
,所以你应该使用%Izu
.
AFAICT、MSVCstd::mutex
进行不可避免的堆分配,因此,std::promise
它使用它。这是一致的行为吗?
这当然值得怀疑std::mutex
应该使用动态分配。它的构造函数不能,因为它必须是constexpr
。它可能会延迟分配,直到第一次调用lock()
or try_lock()
but lock()
没有将获取资源失败列为有效错误条件,这意味着try_lock()
如果无法分配所需的资源,则可能无法锁定无竞争的互斥体。如果你眯着眼睛看的话,这是允许的,但并不理想。
但关于您的主要问题,正如您引用的那样,该标准仅说明了这一点promise
:
第二个构造函数使用分配器a
为共享状态分配内存。
这并没有说明什么other承诺所需的资源。可以合理地假设任何同步对象(如互斥体)都是共享状态的一部分,而不是承诺,但这种措辞并不要求分配器用于共享状态的成员所需的内存,仅用于共享状态所需的内存本身。
For packaged_task
该措辞更广泛,意味着所有内部状态都应该使用分配器,尽管可能有人认为这意味着分配器用于为存储的任务和共享状态获取内存,但同样,共享状态的成员不这样做必须使用分配器。
总之,我认为标准并不是 100% 清楚是否允许 MSVC 实现,但恕我直言,这是一个不需要额外内存的实现malloc
or new
更好(这就是 libstdc++ 的方式<future>
实施工作)。