I have a vector class inside a module:
// other_library.cpp
module;
#include <iostream>
export module mylibrary.other;
export template<class T> class Vector
{
private:
T x, y;
public:
Vector(T _x, T _y) : x(_x), y(_y) {}
void Write()
{
std::cout << "Vector{" << x << ", " << y << "}\n";
}
};
And inside main, I create a vector and print its contents:
// main.cpp
import mylibrary.other;
int main()
{
Vector<int> vec(1, 2);
vec.Write();
return 0;
}
However, I get the unexpected print to terminal:
Vector{10x55a62f2f100c20x55a62f2f100f
These are the build commands used:
g -11 -std=c 20 -fmodules-ts -c other_library.cpp
g -11 -std=c 20 -fmodules-ts -c main.cpp
g -11 -std=c 20 -fmodules-ts *.o -o app
./app
Naturally, if I move the vector class to the main file the print works as expected. I know that module support is still somewhat experimental. But I would expect something simple like this to just work. But perhaps I'm doing something wrong?
EDIT:
A kind-of broken hack is to manually include iostream at the top of the main file, before importing the module, like this:
// main.cpp
#include <iostream>
import mylibrary.other;
int main()
{
Vector<int> vec(1, 2);
vec.Write();
return 0;
}
This will correctly print the contents of the Vector. But why is this necessary? The point of putting stuff in module is to avoid the trouble of header-inclusion.
Thus, my question is now two-fold.
CodePudding user response:
So it seems that there are still some challenges with modules. Example: I cannot use std::endl
inside the Vector.Write
member function.
A solution is to precompile the iostream
standard header, which can be done like this:
g -11 -std=c 20 -fmodules-ts -xc -system-header iostream
The precompiled module will be stored in the gcm.cached/ directory, and will be an implicit search path for consecutive gcc-commands.
Now, I can completely avoid including the standard header, so the library file will look like this now:
// other_library.cpp
export module mylibrary.other;
import <iostream>;
export template<class T> class Vector
{
private:
T x, y;
public:
Vector(T _x, T _y) : x(_x), y(_y) {}
void Write()
{
std::cout << "Vector{" << x << ", " << y << "}"
<< std::endl;
}
};
And I don't need to do anything further in the main file - simply importing my library module is sufficient.
A big thank you to Šimon Tóth for writing about this in his article on modules.