In the code below function f() can call the operator bool() and operator *() member functions of unique_ptr<C> for the incomplete class C. However when function g() tries to call those same member functions for unique_ptr<X<C>>, the compiler suddenly wants a complete type and tries to instantiate X<C>, which then fails. For some reason unique_ptr<X<C>>::get() does not cause template instantiation and compiles correctly as can be seen in function h(). Why is that? What makes get() different from operator bool() and operator *()?
#include <memory>
class C;
std::unique_ptr<C> pC;
C& f() {
    if ( !pC ) throw 0; // OK, even though C is incomplete
    return *pC;         // OK, even though C is incomplete
}
template <class T>
class X
{
    T t;
};
std::unique_ptr<X<C>> pX;
X<C>& g() {
    if ( !pX ) throw 0; // Error: 'X<C>::t' uses undefined class 'C'
    return *pX;         // Error: 'X<C>::t' uses undefined class 'C'
}
X<C>& h() {
    if ( !pX.get() ) throw 0; // OK
    return *pX.get();         // OK
}
class C {};