是否具有不完整数据类型合法的容器的迭代器?

时间:2016-06-11 19:44:26

标签: c++ iterator incomplete-type

以下代码是否合法?

class A
{
    std::map<int, A>::iterator x;
};

Visual Studio 2015接受它,但clang说

.../ndk/sources/cxx-stl/llvm-libc++/libcxx/include/utility:254:9:  
error: field has incomplete type 'A'
    _T2 second;
    ^
....
a.cpp:52:21:
note: definition of 'A' is not complete until the closing '}'
    struct A
           ^

编辑:
问题似乎是标准库,http://rextester.com/QNNEG57036失败了

我的问题是代码是否合法,而不是如何修复它(例如通过更改编译器标志)。

1 个答案:

答案 0 :(得分:4)

除非标准中明确规定不完整类型是合法的,否则它们不合法。具体部分是17.6.4.8 [res.on.functions]第2段:

  

特别是,在以下情况下效果未定义:

     

[...]

     
      
  • 如果在实例化模板组件时将不完整类型(3.9)用作模板参数,除非特别允许该组件。
  •   

我认为不需要任何容器来支持不完整的类型。一些智能指针确实允许不完整的类型。副手我无法想到任何其他允许不完整类型的东西。快速搜索“不完整”会产生以下组件,允许不完整类型作为模板参数:

  • std::declval<T>()
  • std::unique_ptr<T>
  • std::default_delete<T>
  • std::shared_ptr<T>
  • std::weak_ptr<T>
  • std::enable_shared_from_this<T>

在代码示例中,std::map<int, A>::iterator实例化具有不完整类型的模板。因此,代码会导致未定义的行为。