There's a place for Functional overloading, but it can go against the principle of code reuse, which is something you do want to emphasize early. And there's stuff you can do with pointers that you can't do with overloading. Really, you want to teach both tools.
They are not "the same kind of thing" in that context precisely because references aren't optional.
C++ spells "optional argument" with overloaded functions. You don't need to check for null or even explain what null is in that context. You just have two functions which are called with different parameters.
Of course, I've seen people get pointers easier than function overloading, but those people usually come from other languages where such a concept is alien.
In that context, by teaching pointers I meant teaching about indirection, not about how to manually manage memory. Although as long as you emphasize that smart pointers are preferred over manual memory management, I don't think it's out of place to mention why a smart pointer is needed, and how to manually delete things.
It is not only possible; it is to be preferred to teach smart pointers before raw pointers.
Using smart pointers for single elements and `std::vector' for arrays a beginner can pretty much ignore everything about pointers that cause newbies problems.
Using smart pointers beginners also get to ignore some stuff related to exceptions, which trips up a lot of C++ programmers even at the intermediate level, because they will not need to understand how coding for exceptions can strongly alter interface design.
The differences between `malloc', `free', `operator new', `operator delete', the `new' operator, the `delete' operator, the `new' operator, and the `delete' operator can be set aside for a very long time.
I know someone is going to say it, so let me get there first: I never use those functions directly unless I'm writing something very low level. You do not need them "to create something non-trivial".