c – 当包装在模板中时,不完整类型的新的编译器
考虑这个代码,有一个明显的编译错误:(1)
struct A; struct B { B() { new A(); } // error: allocation of incomplete type 'A' }; 使用unique_ptr将无助于:(2) struct A; struct B { B() { std::make_unique<A>(); } // error: due to ~unique_ptr() }; 然后(我的惊喜)我发现,这将编译:(3) struct A; struct B { B() { std::make_unique<A>(); } }; struct A {}; // OK,when a definition is added **below** 然后我检查,这是否有助于新的 – 不是:(4) struct A; struct B { B() { new A(); } // error: allocation of incomplete type 'A' }; struct A {}; 我认为它与模板有关,事实上:在模板中封装新的内容会编译:(5) template <typename T> T* my_new() { return new T(); } // OK,when wrapped in template struct A; struct B { B() { my_new<A>(); } }; struct A {}; 为了完整起见,删除A的定义再次出现错误:(6) template <typename T> T* my_new() { return new T(); } // error: allocation of incomplete type 'A' struct A; struct B { B() { my_new<A>(); } }; // do note: definition of A removed 这里发生了什么?据我所知,编译器必须知道A的大小/定义来分配它,因此仅仅声明它是不够的.另外我相信这个定义必须在分配之前. 这似乎是正确的,当直接使用新的(1,4).但是,当新的包装,显然我错了(2,3,5,6). 到目前为止我发现的可能的解释是: >完成类型的检查将被延迟,直到出现模板实例化.我认为这是正确的,但在我的情况下,直接使用新的A()和对my_new< A>()的调用几乎在同一个位置.所以这不可能是原因.对? 为什么4被认为是不正确的,而5个编译(或者5是只是虚假地编译未定义的行为[但是3必须有缺陷,对吗? btw:用cl -3.5.0和g -4.9.2测试 解决方法
§14.6.4.1[temp.point] / p1,8,强调我的:
在my_new< A>中有两点实例化,一个在B定义的结尾,一个在翻译单元的末尾.由于这两点会导致不同的含义(代码片段3和5),程序是不完整的NDR(即它有未定义的行为). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |