Example for Implementing Functions of Partitions
There were some discussions about the fact that "module M;" imports the
whole interface of M (see
“Uneeded Recompilations When Using Partitions”).
Looking at the external partition
Core/Container/Container.ixx of
our UML Editor, we can see that there is a class IUpdateContainer:
export module Core:Container;
import :Element;
import :Interfaces;
import :Shift;
namespace Core
{
...
export class IUpdateContainer: public virtual IShiftable
{
public:
class Param;
void update(Env&, Param& p);
private:
virtual void updateImpl(Env&, Param& p) = 0;
};
...
That class has a method "update".
For some reason we have decided to implement that method in the file
IUpdateContainer.cpp,
which contains:
module Core;
namespace Core
{
void IUpdateContainer::update(Env& e, Param& p)
{
if (p.add(this))
updateImpl(e, p);
}
}
The consequence of this is, that "module Core;" now implicitly imports all
partitions of the Core module interface:
export module Core;
export import :Attach;
export import :Container;
export import :CopyRegistry;
export import :Diagram;
export import :Element;
export import :Interfaces;
export import :ObjectRegistry;
export import :Selection;
export import :Shift;
export import :Transaction;
export import :Undoer;
export import :View;
export import :Weight;
...
But to compile IUpdateContainer.cpp, only the declarations from the :Container
partition would have been needed.
If "module Core;" would not implicitly import anything, we would write
module Core;
import :Container;
...
and then IUpdateContainer.cpp would still compile fine. All declarations that
are required to compile that file are available by just doing "import :Container;".
Some people may say, that there or no implementation files for partitions.
However, it would have been possible to move the implementation of the
IUpdateContainer::update member function right into the file
Container.ixx. After all, partitions can contain declarations and definitions.
When compiling the partition Container.ixx, the compiler creates both a BMI
file and a .obj file. The BMI file is used for importing into other module
units, the .obj is linked into the binary.
We could say, that a partition can be its own implementation. They do not implicitly import anything, but that still works fine.
Moving the implementation of the member function IUpdateContainer::update into
a separate cpp file (as we did), should just create another .obj. There is no
reason to import anything more than just :Container, if we choose to do
so. Equivalent to when the member function would be implemented right inside
Container.ixx. In one case, the function is in Container.ixx.obj, in the
other case it is in IUpdateContainer.cpp.obj.
The cpp containing "module Core;" could do the same as the partition
"export module Core:Container;" does: Not implicitly import any other
module unit. All declarations that are required to compile any of the two
can be imported explicitly (by the programmer).
I fail to see why the complete declarations of Core should be needed if we have
definitions of member functions in a separate cpp file. The only difference is, that
we have an additional .obj, which is linked into the binary too.
(last edited 2026-04-22)