If the argument is optional, it needs to be a pointer, not a reference.
template<class T>
void f(T** const = 0);
If you want the call-style to be pass-by-reference, then you need a forwarder, not a default argument.
template<class T>
void f_impl(T** const);
template<class T>
void f( T*& arg ) { return f_impl(&arg); }
template<class T>
void f( void ) { return f_impl<T>(0); }
If you want to avoid null checks and just discard assignment to the parameter when no parameter is given, do this:
template<class T>
void f(T*&);
template<class T>
void f( void ) { T* unused = 0; return f(unused); }
Note that T
in the no-argument version is a non-deduced context, but so was the original when no parameter was provided.