在类中将不完整类型的unique_ptr初始化为nullptr

时间:2019-10-14 11:34:55

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

我正在用pimpl惯用法和unique_ptr编写一些代码。当我尝试使用类内初始化将默认情况下将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中修复。

1 个答案:

答案 0 :(得分:4)

该程序,尤其是默认的成员初始化程序,格式正确。如果编译器拒绝编译,那么据我所知这是编译器中的错误。

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