c++ - 类内将不完整类型的 unique_ptr 初始化为 nullptr 时,gcc 编译错误

标签 c++ unique-ptr pimpl-idiom gcc8 in-class-initialization

我正在使用带有 unique_ptr 的 pimpl 惯用法编写一些代码。当我尝试使用类内初始化将 unique_ptr 默认设置为 nullptr 时,gcc 给出了编译错误,而 clang 和 msvc 都成功编译了代码。如果我没有使用类内初始化,错误就会消失。

// A.h
#pragma once

#include <memory>

using namespace std;

class B;
class A
{
private:
    ////////////////////////
    // here gives the error!
    ////////////////////////
    unique_ptr<B> impl{nullptr}; // error only with gcc, 
                                 // ok with clang and msvc
    unique_ptr<B> impl2; // ok with all three

public:
    A();
    ~A();
};
// A.cpp
#include "A.h"

class B
{
private:
    int b{5};

public:
    B() = default;
    ~B() = default;
};

A::A() = default;
A::~A() = default;
// main.cpp
#include "A.h"

int main()
{
    A a;
    return 0;
}

当我编译上面的代码时,gcc 提示“错误:‘sizeof’对不完整类型‘B’的无效应用”。我尝试过 gcc 8.3 和 gcc 9.1 但没有成功。这是编译器错误吗?谢谢!

编辑: 我按照@eerorika的建议尝试了。如果头文件和源文件合并为一个文件,则可以正常编译,但不能分开。

编辑 确认是编译器错误,并已在 gcc9.2 中修复。

最佳答案

该程序,特别是默认成员初始化程序,格式良好。如果编译器拒绝编译,那么据我所知,这是编译器中的一个错误。

我可以使用 GCC 9.1 重现该问题,但不能重现 9.2 或 trunk,因此它似乎已得到修复。对于旧版本,您可能需要放弃使用默认成员初始化程序作为解决方法。

关于c++ - 类内将不完整类型的 unique_ptr 初始化为 nullptr 时,gcc 编译错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58375922/

相关文章:

c++ - Pimpl 成语内存使用

c++ - 实现Z缓冲区算法

c++ - 实现 T9 文本预测

c++ - 为什么我可以使用 make_unique 创建带有衰减数组指针的 unique_ptr?

c++ - 将 std::unique_ptr 插入 std::set

c++ - 声明现有原始指针所有权的正确方法

c++ - 当全局函数需要指向 impl 的指针时,如何防止 impl 细节出现在头文件中?

c++ - Pimpl 成语 vs 纯虚拟类接口(interface)

c++ - Visual Studio跳过多个if语句?

c++ - 我可以使用桥接 header 在基于 Swift 的项目中导入 Objective-C++ 类吗?