I have been tossing this idea in my mind for almost 20 years. The current schema of overloading operator new belongs to dinosaur era IMO.If we could provide operator new with the requested type - instead of just its size (and optionally alignment), then the return type could also be a custom allocator (rather just void*). This in turn would enable the new expression to return a smart pointer - rather than a dangerous raw pointer:
smart_allocator operator new(compiler_provided_params,user_provided_params) value_type { /*...*/};
The corresponding new expression:
auto ptr=new(user_provided_args) value_type {initializer_args};
Would then generate pseudo code sequence like this:
auto ptr = [&}(){
smart_allocator temp_alloc{ operator new(compiler_provided_args,user_provided_args) value_type };
smart_pointer ret=temp_alloc(initializer_args);
return std::move(ret);
}();
The exact type and number of compiler provided parameters is open to discussion, but it must at least provide the following functionality:
auto constructor_lambda(compiler_provided_params){
return [](void * void_this, auto && ... initializer){
::new(__none_overloadable_placement__ , void_this) value_type {std::forward<decltype(initializer)>(initializer) ... };
};
};
the multi-lambda in the above pseudo snippet shall correspond to all accessible overloads of constructors of value_type in the context of calling new-expression. other functionality such as destructor accessibility and assignment operator overload set may also be considered, but avialablity of accessible constructors is of prime essence IMHO.
This proposition is aiming at encouraging the usage of raw pointers as observer-only idiom. I am trying to combine the syntax clarity of new with safety of make_smart family of convenience functions. Other benefits include:
- passing the whole type - instead of just its size - to the operator new enables safely conveying meta-data about exact type of object to runtime such as clonabilty true destructor. One problem with traditional new-expression is destructor slicing of none-polymorphic hierarcies (that this proposition can help avoid):