Custom allocators vs. promises and packaged tasks

流过昼夜 提交于 2019-12-05 05:39:00

N.B. there are a couple of issues with your code. In C++14 if you replace operator delete(void*) then you must also replace operator delete(void*, std::size)t). You can use a feature-test macro to see if the compiler requires that:

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

Secondly the correct printf format specifier for size_t is zu not u, so you should be using %Izu.

AFAICT, MSVC's std::mutex does an unavoidable heap allocation, and therefore, so does std::promise which uses it. Is this a conformant behaviour?

It's certainly questionable whether std::mutex should use dynamic allocation. Its constructor can't, because it must be constexpr. It could delay the allocation until the first call to lock() or try_lock() but lock() doesn't list failure to acquire resources as a valid error condition, and it means try_lock() could fail to lock an uncontended mutex if it can't allocate the resources it needs. That's allowed, if you squint at it, but is not ideal.

But regarding your main question, as you quoted, the standard only says this for promise:

The second constructor uses the allocator a to allocate memory for the shared state.

That doesn't say anything about other resources needed by the promise. It's reasonable to assume that any synchronization objects like mutexes are part of the shared state, not the promise, but that wording doesn't require that the allocator is used for memory the shared state's members require, only for the memory needed by the shared state itself.

For packaged_task the wording is broader and implies that all internal state should use the allocator, although it could be argued that it means the allocator is used to obtain memory for the stored task and the shared state, but again that members of the shared state don't have to use the allocator.

In summary, I don't think the standard is 100% clear whether the MSVC implementation is allowed, but IMHO an implementation that does not need additional memory from malloc or new is better (and that's how the libstdc++ <future> implementation works).

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!