Touloudou
Touloudou

Reputation: 2223

hpp/cpp split of C++20 module implementation partitions

I have a large class Foo that I want to turn into a module partition. This class is only used internally, so I don't need to export any symbol. A module implementation partition should do:

export module parent;
import :foo;

with

module parent:foo;
class Foo { ... }; urg! I need to add the full implementation here, no more hpp/cpp split

I could hack my way around the issue by having a module interface partition parent:foo that would contain my header file but wouldn't export anything. I am not a big fan of the idea though.

What is the recommended approach here? Should the "old-fashioned" hpp/cpp split die with modules, when nothing is to be exported?

Upvotes: 2

Views: 1754

Answers (3)

alexpanter
alexpanter

Reputation: 1578

You don't need any header files when working with modules. This is the core idea of introducing modules to the language - to gradually terminate the need for header-inclusion. Your example code looks perfectly fine, especially if you want the Foo class to only be visible inside the module:

// parent.cpp
export module parent;
import :foo;

// Here we can use all functionality provided by
// the foo partition without worrying that it will
// be leaked outside this module.
// parent-foo.cpp

// All code in here will only be visible inside the
// parent.cpp file.

module parent:foo;
class Foo { /* ... */ };

Alternatively, you can also place everything in one file if you will. The compiler will not care, though that file may become large:

// parent.cpp
export module parent;

class Foo { /* ... */ } // not visible outside this module!

export
{
    // Everything placed in here will be visible to other
    // files that import this module.
}

Upvotes: 2

Davis Herring
Davis Herring

Reputation: 39798

You can still use separate source files in much the same fashion:

module parent:foo;
class Foo {
  void f();
};
module parent;
import :foo;

void Foo::f() {}

The latter implementation unit, being only definitions of functions declared elsewhere, need not be imported anywhere, just linked as usual. The same approach applies to exported classes except that they must of course be declared in an interface unit.

Whether you want this structure for the future is a separate question: modules may make your build fast enough even without the duplicative isolation, and your implementation may, as a feature, decline to inline functions not declared inline in a module unit (even if defined inside a class) to provide ABI stability.

Upvotes: 4

Caleth
Caleth

Reputation: 62636

If you want to keep your file structure, there's nothing stopping you from converting

foo.hpp

class Foo { ... };

foo.cpp

#include "foo.hpp"

Foo::Foo() ...

Into

foo.hpp

module parent:foo;
class Foo { ... };
#include "foo.cpp"

foo.cpp

Foo::Foo() ...

Upvotes: 0

Related Questions