C ++ 11:unique_ptr抱怨不完整的类型,但不包括它

时间:2013-08-24 23:01:54

标签: c++

在SO上已经有很多关于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 1}}也在第二个。也, 当将unique_ptr包装在结构中时,为什么第一种情况有限制?

更新

在DietmarKühl回答之后,我认为问题可以归结为以下几点:

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;
};

1 个答案:

答案 0 :(得分:3)

第一种情况下的问题是不完整类型与std::unordered_map<K, Impl<K, T>一起使用:要确定iterator是什么,std::unordered_map<K, Impl<K, T>的部分需要在{{1}时实例化只是声明了。 Impl与错误没有关系。您可以删除使用std::unique_ptr<...>作为iter_type的需要来验证它是否为类型。

另一方面,在将迭代器类型的使用包装到typedef中时,在构造函数实现之前不使用此嵌套类型。当然,内联定义函数的行为就像类刚刚完全定义一样,它们只是在类定义之外实现,即上面的代码等同于

Wrapper

也就是说,当需要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(); }; template<typename K, typename T> Impl<K, T>::Impl() : ptr(new Impl<K, T>::Wrapper()) {} 的定义并进行实例化时,Wrapper被定义。