gpt4 book ai didi

c++ - 新的不完整类型在包装在模板中时编译

转载 作者:太空宇宙 更新时间:2023-11-04 13:12:51 24 4
gpt4 key购买 nike

考虑这段代码,有一个明显的编译错误:(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**

然后我检查了这是否有助于 new还有 - :(4)

struct A;
struct B {
B() { new A(); } // error: allocation of incomplete type 'A'
};
struct A {};

我认为它与 template 有关s 和事实上:包装 newtemplate 里面是否编译:(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的大小/定义|分配它,因此仅仅声明它是不够的。此外,我认为定义必须先于分配。

这似乎是正确的,当使用 new直接 (1,4)。但是当new被包裹起来,很明显我错了(2,3,5,6)。

目前我发现的可能的解释是:

  • 完成类型的检查延迟到template。实例化发生。我认为这是正确的,但在我的例子中,直接使用 new A()并调用my_new<A>()几乎发生在同一个位置。所以这不能成为原因。对吧?
  • 使用不完整的类型作为 template参数可能是未定义的行为。这是真的吗?即使启用所有警告,编译器也不会提示。此外,比较 5 和 6 似乎表明,编译器足够聪明,可以找出下面的定义(因此实际上使类型完整)。

为什么 4 被认为是不正确的,而 5 可以编译(或者 5 只是虚假地编译了未定义的行为 [但是 3 一定也有缺陷,对吧?])?

顺便说一句:使用 clang++-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++ - 新的不完整类型在包装在模板中时编译,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38926802/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com