c – 当包装在模板中时,不完整类型的新的编译器

c – 当包装在模板中时,不完整类型的新的编译器,第1张

概述考虑这个代码,有一个明显的编译错误:(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 考虑这个代码,有一个明显的编译错误:(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 templatestruct 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>()的调用几乎在同一个位置.所以这不可能是原因.对?
>使用不完整的类型作为模板参数可能是未定义的行为.这是真的吗即使启用所有警告,编译器也不会抱怨.比较5和6似乎表明,编译器足够聪明,可以确定下面的定义(从而实际上使得类型完整).

为什么4被认为是不正确的,而5个编译(或者5是只是虚假地编译未定义的行为[但是3必须有缺陷,对吗?

btw:用cl -3.5.0和g -4.9.2测试

解决方法 §14.6.4.1[temp.point] / p1,8,强调我的:

1 For a function template specialization,a member function template
specialization,or a specialization for a member function or static
data member of a class template,if the specialization is implicitly
instantiated because it is referenced from within another template
specialization and the context from which it is referenced depends on
a template parameter,the point of instantiation of the specialization
is the point of instantiation of the enclosing specialization.
Otherwise,the point of instantiation for such a specialization
immediately follows the namespace scope declaration or deFinition that
refers to the specialization.

8 A specialization for a function template,a member function template,
or of a member function or static data member of a class template may
have multiple points of instantiations within a translation unit,and
in addition to the points of instantiation described above,for any
such specialization that has a point of instantiation within the
translation unit,the end of the translation unit is also consIDered a
point of instantiation. A specialization for a class template has at
most one point of instantiation within a translation unit. A
specialization for any template may have points of instantiation in
multiple translation units. If two different points of instantiation
give a template specialization different meanings according to the one
deFinition rule (3.2),the program is ill-formed,no diagnostic
required.

在my_new< A>中有两点实例化,一个在B定义的结尾,一个在翻译单元的末尾.由于这两点会导致不同的含义(代码片段3和5),程序是不完整的NDR(即它有未定义的行为).

总结

以上是内存溢出为你收集整理的c – 当包装在模板中时,不完整类型的新的编译器全部内容,希望文章能够帮你解决c – 当包装在模板中时,不完整类型的新的编译器所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/langs/1243692.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-06
下一篇 2022-06-06

发表评论

登录后才能评论

评论列表(0条)

保存