Reputation: 1103
I have a simple project with one module.
Units.ixx
module;
#include <cassert>
export module Units;
export class Base {
public:
};
export void foo();
Units_impl.ixx
export module Units;
class Derived : public Base { // 'Base': base class undefined
};
export void foo() {
Derived derived;
}
Main.cpp
import Units;
int main() {
return foo();
}
Compiler shows me an error 'Base': base class undefined. Is it expected behavior? If yes, how to divide modules into submodules? I’d like to have Derived inside my Units module but in a different file.
Upvotes: 4
Views: 3996
Reputation: 2073
Module.ixx
export module mybar;
export import :Wheel;
export import :Bus;
Wheel.ixx
export module mybar:Wheel;
export
class Wheel{
};
Bus.ixx
export module mybar:Bus;
import :Wheel;
export
class Bus :public Wheel {
};
Upvotes: 3
Reputation: 239
To split a module into multiple files you need to use partitions. To do this you need to first create a primary interface:
export module Units;
then you declare each separate file that makes up the module as a named partition(export module <module_name>:<partition_name>) eg:
export module Units:Impl;
This does not by itself share classes, variables or functions between the files though. To access a partition from the primary interface or another partition you need to add an import statement import :<partition_name> eg:
import :Impl;
so in the code you have above Units_impl.ixx knows nothing about Base
as it is declared in a separate file hence the error.
This also means you cannot declare the class Base in the primary interface if you want to have access to it from a partition as this would result in a cyclic dependancy. Ie the partition would need to import Units(the primary interface) which would itself need to import the partition(Units:Impl). So at the very least your files would need to look something like:
Units.ixx:
export module Units;
import :Impl;
export void foo();
Units_Impl.ixx:
class Base{};
class Derived: public Base{};
export void foo()
{
Derived derived;
}
Main.cpp:
import Units;
int main()
{
foo();
return 0;
}
If you didn't want Base to be in the same file as Derived you'd need to create another partition in a separate file eg:
Units_Base.ixx:
export Units:Base;
export class Base{};
and then your Units_Impl.ixx would look like this:
export Units:Impl;
import :Base;
class Derived: public Base{};
export void foo()
{
Derived derived;
}
Finally you can re-export from an imported module using export import <module_or_partition_name> eg:
export import :Impl;
this would then make export void foo();
in Units.ixx unnecessary and it would look like this:
export module Units;
export import :Impl;
Upvotes: 2