關於unique_ptr和不完整類型已經有很多關於SO的問題,但沒有人能給我一個概念來理解爲什麼以下不會工作:C++ 11:unique_ptr抱怨不完整的類型,但不是當我包裝它時
// error: ... std::pair<...>::second has incomplete type
template<typename K, typename T> struct Impl {
typedef typename std::unordered_map<K,Impl<K,T>>::iterator iter_type;
std::unique_ptr<iter_type> ptr;
Impl() : ptr(new iter_type()) {}
};
int main() { Impl<int,int>(); return 0; }
而以下作用:
template<typename K, typename T> struct Impl {
struct Wrapper {
typedef typename std::unordered_map<K,Impl<K,T>>::iterator iter_type;
iter_type iter;
};
std::unique_ptr<Wrapper> ptr;
Impl() : ptr(new Wrapper()) {}
};
int main() { Impl<int,int>(); return 0; }
我沒有看到那裏的技術區別是:如果std::pair<...>::second
(即Impl<K,T>
)是不完整的,以Impl
在第一個例子,它應該是不完整的第二個也是Wrapper
。另外,如果將unique_ptr
包裝在一個結構中就足夠了,那麼 ,爲什麼第一種情況會有限制?
UPDATE:
迪特馬爾·庫爾的回答後,我認爲這個問題可以歸納爲以下:
template<typename K, typename T> struct Impl {
typename std::unordered_map<K,Impl<K,T>>::iterator ptr;
};
VS
template<typename K, typename T> struct Impl {
struct Wrapper {
typename std::unordered_map<K,Impl<K,T>>::iterator iter;
};
Wrapper *ptr;
};
你的意思是不同之處在於''Impl'類被認爲**完全實現之前''Wrapper'構造函數沒有被編譯?所以包裝者只是在編輯順序可能完全相同的情況下,將整個構建過程人爲地分爲兩步: –
@JoSo:類模板的成員在使用時被實例化。 'Wrapper'是一個類模板的成員,它只用於構造函數的定義。 'typedef'實際上不是一個成員,並且定義類模板'Impl'它是一種實例化的類。所以,是的,使它成爲一個兩階段的過程,避免了類型的問題,但尚未被定義。 –
不應該有辦法告訴編譯器「是的,這種類型真的存在!」?我的意思是,我也可以說'struct NewType; NewType * ptr;'在課堂內部沒有定義NewType並且它可以工作!這只是規範/實施方面的弱點,還是背後有更深層次的原因? –