gpt4 book ai didi

c++ - 类型不完整的唯一指针 - C++2b?

转载 作者:行者123 更新时间:2023-12-02 15:46:39 24 4
gpt4 key购买 nike

归结为:

#include <memory>
class dummy;

std::unique_ptr<dummy> test;

class dummy {

};

当使用 clang++-14 和 c++2b 编译时:

它简要地给出了:

clang++ ../bugl.cpp -I /usr/lib/llvm-14/include  -std=c++2b
In file included from ../bugl.cpp:1:
In file included from /usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/memory:76:
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:93:16: error: invalid application of 'sizeof' to an incomplete type 'dummy'
static_assert(sizeof(_Tp)>0,
^~~~~~~~~~~
/usr/bin/../lib/gcc/x86_64-linux-gnu/12/../../../../include/c++/12/bits/unique_ptr.h:396:4: note: in instantiation of member function 'std::default_delete<dummy>::operator()' requested here
get_deleter()(std::move(__ptr));
^
../bugl.cpp:4:24: note: in instantiation of member function 'std::unique_ptr<dummy>::~unique_ptr' requested here
std::unique_ptr<dummy> test;
^
../bugl.cpp:2:7: note: forward declaration of 'dummy'
class dummy;
^
1 error generated.

但是一旦我们删除了 dummy 的定义,它就变得有趣了——然后它在任何地方都同样失败。

最初我是从 llvm-14 头文件中找到它的:

#include <memory>
#include <llvm/ADT/APFloat.h>

在 Ubuntu 22.04.1 LTS 中使用 llvm-14 和 libstdc++-12-dev 以及 clang++-14

编译:

clang++ -std=c++2b bugllvm.cpp

使用 -std=c++20 可以很好地编译(以及使用 g++ 的 20 和 2b)。

基本上有问题的是这一行:

class DoubleAPFloat final : public APFloatBase {
// Note: this must be the first data member.
const fltSemantics *Semantics;
std::unique_ptr<APFloat[]> Floats;

此处声明了 APFloat 但未定义:

class APFloat;

我的问题是错误在哪里 - 在编译器、标准库、标准本身?

也许是别的原因。

最佳答案

问题是没有使用 std::unique_ptr作为这样的成员。实际问题在 operator= 的实现中的类定义中更进一步。第 625 行:

DoubleAPFloat &operator=(DoubleAPFloat &&RHS) {
if (this != &RHS) {
this->~DoubleAPFloat();
new (this) DoubleAPFloat(std::move(RHS));
}
return *this;
}

析构函数调用导致 DoubleAPFloat 的析构函数被定义为。这需要 std::unique_ptr<APFloat[]> 的析构函数被实例化。该析构函数的实例化需要实例化 std::default_delete<APFloat[]>operator()这又需要 APFloat完成。

函数模板特化的实例化有两个实例化点。一个紧跟在需要它的命名空间范围声明之后(或在需要它的模板实例化点),第二个在翻译单元的末尾。如果选择其中之一而不是另一个会给程序带来不同的含义,则该程序格式错误,不需要诊断

APFloat稍后在头文件中定义,因此这里适用。 std::default_delete<APFloat[]>::operator() 的实例化在 DoubleAPFloat 的定义之后立即变为病式(其中 std::unique_ptr 的析构函数的实例化有一个实例化点),但它在翻译单元的末尾会是良构的。

所以这是 <llvm/ADT/APFloat.h> 中的错误编译器不必诊断。


这同样适用于您的简化测试用例。 test的定义需要定义析构函数,因为需要它来析构变量。同样,隐式实例化可以紧接在变量定义之后或翻译单元的末尾放置。没有 dummy 的定义最后,两个实例化点都是病式的,因此现在需要编译器对其进行诊断。

关于c++ - 类型不完整的唯一指针 - C++2b?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73978544/

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