以下代码是否合法?
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失败了
我的问题是代码是否合法,而不是如何修复它(例如通过更改编译器标志)。
答案 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
实例化具有不完整类型的模板。因此,代码会导致未定义的行为。