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

Dan*_*ani 6 c++ iterator incomplete-type

以下代码是否合法?

class A
{
    std::map<int, A>::iterator x;
};
Run Code Online (Sandbox Code Playgroud)

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
           ^
Run Code Online (Sandbox Code Playgroud)

编辑:
问题似乎与标准库有关,http: //rextester.com/QNNEG57036失败

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

Die*_*ühl 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实例化了具有不完整类型的模板。因此,代码会导致未定义的行为。