Implementing `create` and `destroy` functions to replace `new` and `delete` operators
After some research, I'm convinced Christopher Creutzig is right. If you want all your allocations to go through customized functions, you're much better off replacing the global operator new. This will catch all calls to new for the translation unit, whether you replace them with create or not. That means when you create a std::vector&lt;T&gt; myvec(3), it will use your operator new for any heap allocations it needs to do, instead of sidestepping your global policy.

If you need to pass a module id, operator new can handle that as well by accepting extra parameters. I'm unclear how that mixes with examples such as the std::vector&lt;T&gt; heap allocations; it may require using a custom allocator for each STL container. Setting that aside, here's an example like yours following the lead on cppreference.com:

void* operator new(std::size_t cb, uint32_t module_id)
{
    // use module_id
    return calloc(1, cb);
}
void operator delete(void* ptr)
{
    free(ptr);   // I'm unsure if this requires a null check
}

type *p = new(module_id) type;


As an aside, if you're particularly tied to calling functions, I'd be tempted to remove the SFINAE specialization via is_pod&lt;T&gt; and just make it an inline check via is_trivially_constructible&lt;T&gt; and is_trivially_destructible&lt;T&gt;...that is if checking is necessary at all.

template&lt;typename T&gt;
T* create(uint32_t module_id)
{
    // use module_id
    T* p = calloc(1, sizeof(T));
    if (!is_trivially_constructable&lt;T&gt;::value &amp;&amp; p)
    {
        new (p) T(forward&lt;Args&gt;(args)...);
    }
    return p;
}