In the mid 00s, my advisor had me explore the concept of adding default parameters to C++ functions where the default snagged the nearest lexically scoped named object of the right type from the calling environment, i.e.,
int someFunctionThatAllocates(int A, int B, allocator const& alloc = default);
Then in the calling environments:
{
auto& alloc = james;
if (someFunctionThatAllocates(4, 5)) // ok, uses 'alloc'
{
}
}
{
if (someFunctionThatAllocates(4, 5, james)) // ok, uses 'james'
{
}
}
{
auto& alloc1 = james;
if (someFunctionThatAllocates(4, 5)) // error: no `alloc` in scope
{
}
}
It handily solves a number of problems. In particular, we were looking at how we manage heap allocation for large sparse matrix libraries a la MTL4.