I'm actually trying to understand the C++20 modules system by writing my own little module. Let's say I want to provide a function that deletes all the spaces at the beginning and the end of a string (a trim
function). The following code works without problem.
module;
export module String;
import std.core;
export std::string delete_all_spaces(std::string const & string)
{
std::string copy { string };
auto first_non_space { std::find_if_not(std::begin(copy), std::end(copy), isspace) };
copy.erase(std::begin(copy), first_non_space);
std::reverse(std::begin(copy), std::end(copy));
first_non_space = std::find_if_not(std::begin(copy), std::end(copy), isspace);
copy.erase(std::begin(copy), first_non_space);
std::reverse(std::begin(copy), std::end(copy));
return copy;
}
import std.core;
import String;
int main()
{
std::cout << delete_all_spaces(" Hello World! \n");
return 0;
}
But what if I want to use only specific headers instead of std.core
in my module? If I do so, replacing the import std.core
by the following code, I get an error on Visual Studio 2019.
module;
#include <algorithm>
#include <cctype>
#include <string>
export module String;
// No more import of std.core
export std::string delete_all_spaces(std::string const & string)
{
// ...
}
Error LNK1179 file not valid or damaged: '??$_Deallocate@$07$0A@@std@@YAXPAXI@Z' COMDAT duplicated
However, if in the main.cpp
I remplace as well the import std.core
with #include <iostream>
, the code compiles again. It's like using both system provents the linker to do its job.
The question is: am I doing it wrong? Is it a bad practice to use both the new import
and the old #include
methods? I saw on multiple posts on the Internet that you can include some old headers in your module, thus modernizing your code without breaking the existing. But what if this header includes some part of the STL, like #include <string>
but my module uses import std.core
?
I'm testing only with Visual Studio 2019 because, as of now, import std.core
does not work with GCC. So, may it comes from a bug in VS? Or will the problem be the same for all compilers?
Modules eliminate or reduce many of the problems associated with the use of header files. They often reduce compilation times. Macros, preprocessor directives, and non-exported names declared in a module aren't visible outside the module.
A module header specifies linkage information that the compiler or executor uses to resolve names mentioned within the module body. Unlike the bulk of an Avail program, which uses an extremely fluid syntax, a module header has a rigid structure that revolves around a small vocabulary of fixed keywords.
Add a module unit implementation file by creating a source file with a right-click in the Solution Explorer on Source Files, select Add > New item and then select C++ File (. cpp). Give the new file the name BasicPlane.
Modules are the new C++20 method for importing functions and classes from external libraries and separate translational units. Modules provide an alternative to using header files. Some of the benefits of modules are: No need to write separate files for the interface ( .h) and the implementation ( .cpp)
Precompiled headers can be a very effective way of speeding up compile times. Also, removing implementation details from the interface file (e.g. using the PIMPL idiom) reduces the ‘ripple effect’ and prevents unnecessary recompilation when small changes are introduced. Defining and using modules in C++20 requires the use of the following tokens:
Technically, export is an existing C++ keyword which takes on a new significance in C++20, whereas import and private become identifiers with special meaning. A module is a way of packaging code (e.g. a library or API) for reuse. A module is referenced by name rather than by the header file it lives in, e.g.:
Which headers are importable is implementation-defined, but the C++ standard guarantees that all standard library headers are importable headers. The ability to import excludes C headers. What's Next? In my next post, I use variadic templates to implement the C++ idiom for a fully generic factory.
Yes, modules can be used together with header files. we can both import and include headers in the same file, this is an example:
import <iostream>
#include <vector>
int main()
{
std::vector<int> v{1,6,8,7};
for (auto i:v)
std::cout<<i;
return 0;
}
When you create modules, you're free to export entities in the interface file of the module and move the implementations to other files. to conclude, the logic is the same as in managing .h and .cpp files
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With