В приведенном ниже коде функция 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 {};