0

Consider the following short but multifile example:

// ************************** unit.h **************************
#pragma once

#include <memory>

struct S;

struct B {
    B(int) {};
    virtual ~B() {};
};

struct D : B {
   D(int);
   ~D() override;
   std::unique_ptr<S> p;
};

// ************************** unit.cpp **************************
#include "unit.h"

struct S {};

D::D(int i) : B(i) {}

D::~D() = default; 

// ************************** prog.cc **************************
#include "unit.h"

int main()
{
    D d(42);
}

There are two classes with inheritance: base B and derived D. D class contains a unique_ptr member definition with only declared class S. To make this scheme work I need to define both constructor and destructor of class D out-of-line (i.e. implemented in unit.cpp, where the full definition of S is visible).

The question: is it possible to use the using B::B; declaration in the D class inherit the B's constructors to prevent writing manually D::D(int i) : B(i) {}, but make this inheritance out-of-line in order to prevent compilation error?

error: invalid application of 'sizeof' to an incomplete type 'S'
αλεχολυτ
  • 4,792
  • 1
  • 35
  • 71

1 Answers1

2

is it possible to use the using B::B; declaration in the D class inherit the B's constructors to prevent writing manually D::D(int i) : B(i) {}

It is possible.

Along with the forward declaration of struct S also declare its deleter:

struct S;

struct SDeleter { void operator()(S*) const; }; // Defined elsewhere.

And then:

struct D : B {
   using B::B;
   std::unique_ptr<S, SDeleter> p;
};

The definition of void SDeleter::operator()(S*) const must be provided in another translation unit (.cc) that has access to the definition of S.

Maxim Egorushkin
  • 131,725
  • 17
  • 180
  • 271