В приведенном ниже коде функция f() может вызывать функции-члены operator bool() и operator *() для unique_ptr<C> для неполного class C. Однако, когда функция g() пытается вызвать те же функции-члены для unique_ptr<X<C>>, компилятор внезапно хочет получить полный тип и пытается создать экземпляр X<C>, который затем не выполняется. По какой-то причине unique_ptr<X<C>>::get() не вызывает создание шаблона и компилируется правильно, как видно из функции h(). Почему это? Что отличает get() от operator bool() и 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 {};