I have been experimenting with C 20 modules, and there seems to be something different with the usual hpp/cpp approach. The following doesn't compile (I'm using the latest preview of MSVC).
foo.ixx
export module foo;
import std.memory;
export
struct Bar;
export
struct Foo {
std::unique_ptr<Bar> ptr;
};
bar.ixx
export module bar;
import std.core;
import foo;
struct Bar {
void func(Foo& f) {}
};
main.cpp
import foo;
import bar;
int main() {
Foo f;
}
My questions:
- Is there a better way to resolve this other than putting
Foo
andBar
into one file? - Does this imply that template instantiation is done before module "linking"?
CodePudding user response:
Modules own the declarations placed into them. And if a module owns a declaration, all other declarations must also be part of the same module.
Bar
was declared to be in foo
. Therefore, any other declarations of it (and a definition is a declaration) must also be within foo
.
They don't have to be in the same file, but they do have to be in the same module. If you want the definition of Bar
to be accessible by users of the module foo
, you should use a module interface unit partition:
export module foo:BarDef;
import std.core;
export struct Bar {
void func(Foo& f) {}
};
And the module's primary interface unit must import this partition:
export module foo;
import std.memory;
export struct Bar;
export struct Foo {
std::unique_ptr<Bar> ptr;
};
export import :BarDef;
MSVC's naming convention for module files says that .ixx
should be used for any interface units, so both of these files should be .ixx
files.