inconsistent behavior with user-defined new and delete
 
We all know that a new-expression,
    foo* a = new foo() ;
allocates memory for a single foo then calls foo::foo().  And we know
that
    void* p = ::operator new(sizeof(foo)) ;
allocates a sizeof(foo)-sized buffer but does NOT call foo::foo().
So only new-expressions both allocate and initialize.  Fair enough.
Now suppose we wish to use a custom memory pool,
    my_pool pool ;
    foo* a = new(pool) foo() ;
This calls
    void* operator new( std::size_t size, my_pool & )
                        throw(std::bad_alloc) ;
and then calls foo::foo().  Naturally we also define
    void operator delete( void* data, my_pool & ) throw() ;
But how are we going to call our custom delete?
    my_pool pool ;
    foo* a  = new(pool) foo() ;
    // compile error
    delete(pool) a ;
    // calls the default operator delete(), not our delete
    delete a ;
    // does not call foo::~foo()
    ::operator delete(a, pool) ;
    // is this the idiom, then?
    a->~foo() ;
    ::operator delete(a, pool) ;
There appears to be no such delete-expression to complement the
new-expression.  Why the inconsistency?  Surely this is an oversight
in the design of C++?  In particular I expected "delete(pool) a" to
work.
To recap, we have a mechanism for default-allocate-then-construct
(no-argument new-expressions) and for destruct-then-default-deallocate
(no-argument delete-expressions).  Furthermore, we have a mechanism
for custom-allocate-then-construct (custom new-expressions), but NOT
for destruct-then-custom-deallocate (no custom delete-expressions).
One workaround is to define operator new() and operator delete()
inside foo, but suppose I can't do that.  Another workaround is to use
    template< typename pool_type, typename T >
    void custom_delete( pool_type & pool, T* p )
    {
        p->~T() ;
        pool.deallocate(p, sizeof(T)) ;
    }
but this just begs the question of why that should be necessary, i.e.,
why no delete-expressions, i.e. delete(pool) p.
Incidentally this begs a more general question: since a custom
operator new() defined outside of a class will not work with auto_ptr,
one wonders what is the point of such operator new()s.  Surely someone
will eventually use auto_ptr with it by accident, wreaking havoc when
the wrong delete is called from auto_ptr::~auto_ptr().  This seems to
suggest that "delete p" should automagically call
    void operator delete( void* data, my_pool & ) throw() ;
however that is probably impossible to implement efficiently (relative
to current C++ implementations).  Another option is for the auto_ptr
constructor to take an optional (de)allocator but that relies on
programmers remembering to do so, which doesn't solve the problem but
just moves it around.
#include <iostream>
#include <ostream>
class my_pool
{
} ;
void* operator new( std::size_t size, my_pool & )
throw(std::bad_alloc)
{
    std::cerr << "my_pool operator new" << std::endl ;
    return ::operator new(size) ;
}
void operator delete( void* data, my_pool & ) throw()
{
    std::cerr << "my_pool operator delete" << std::endl ;
    return ::operator delete(data) ;
}
struct foo
{
    foo()
    {
        std::cerr << "foo::foo()" << std::endl ;
    }
    ~foo()
    {
        std::cerr << "foo::~foo()" << std::endl ;
    }
} ;
int main()
{
    my_pool pool ;
    foo* a  = new(pool) foo() ;
    // compile error
    //delete(pool) a ;
    // calls the default operator delete(), not ours
    //delete a ;
    // does not call foo::~foo()
    //::operator delete(a, pool) ;
    // is this the idiom, then?
    a->~foo() ;
    ::operator delete(a, pool) ;
    return 0 ;
}