The "framework issue" you describe is solved precisely by specifying ownership semantics in terms of smart pointer return values. The way everyone becomes "100% sure what that return means" is by whether it returns a `unique_ptr` or a `shared_ptr`. The OP is simply complaining that `auto` takes away that local information on ownership.
`operator new()` is only trivial by virtue of not specifying anything at all about ownership. `scoped_ptr` and `shared_ptr` and `unique_ptr` are each specifying different, more restricted, but still trivial ownership semantics. They aren't "deep C++ voodoo" in the least. Your post smacks of someone who doesn't actually write C++ for a living.
You are conflating required language features with proper API design and documentation. I don't need '(unique|scoped|shared)_ptr' to refrain from aliasing mutable types, or to document my code properly on the rare occasion when I am required to.
int^ foo(int% bar);
versus: std::unique_ptr<int> foo(std::shared_ptr<int> bar);
Smart pointers have long been available in boost and are required for writing safe code, but they make code unreadable (even after typedefs).But if you really need a compact notation for smart pointers, you'll get pretty close by using template aliases, e.g.
template <typename T> using up = std::unique_ptr<T>;
template <typename T> using sp = std::shared_ptr<T>;
// ...
up<int> foo(sp<int> bar) {
return bar ? up<int>(new int(*bar)) : nullptr;
}