Coming in C++20
The main features in C++20 of interest to scientific computing are:
Modules
Modules are source files that are compiled independently of your program that can then be imported. They replace the role of headers in C++20. Note that compiler support is not that great at the moment.
See Overview of modules in C++
One of the advantages of modules is that they can greatly speed up compilation times.
Note
Compiler support for modules is not very good at the moment.
Here’s a simple example. First the module:
module;
// includes must be in the "global fragment" and preced the main
// purview that's why we add the `module;` above.
#include <cmath>
export module Example;
export double f(double x) {
return std::sin(x);
}
Now the main program:
import Example;
#include <iostream>
int main() {
double x{0.0};
std::cout << f(x) << std::endl;
}
and finally, a GNUmakefile
:
MODULEFILES := example.cpp
SOURCEFILES := main.cpp
MODULEOBJS := $(MODULEFILES:.cpp=.o)
SOURCEOBJS := $(SOURCEFILES:.cpp=.o)
ALL: main
%.o : %.cpp
g++ -std=c++20 -fmodules-ts -c $<
system_headers:
g++ -std=c++20 -fmodules-ts -x c++-system-header iostream
main: system_headers ${MODULEOBJS} ${SOURCEOBJS}
g++ -std=c++20 --modules-ts -o $@ ${MODULEOBJS} ${SOURCEOBJS}
clean:
rm -rf *.o main gcm.cache
Note
This compiles with GCC 11.4, but curiously not with GCC 14…
Concepts
Views
C++ 20 introduces the ranges library. This allows us to more easily consider views into our containers.
Here’s an example of using a range-based for loop over a set of integers:
#include <iostream>
#include <ranges>
int main() {
for (auto i : std::views::iota(2, 7)) {
std::cout << i << std::endl;
}
}
Range Adaptors
Range adaptors look like pipes that we saw when discussing Bash (see: https://learn.microsoft.com/en-us/cpp/standard-library/range-adaptors?view=msvc-170)
Here’s an example of using an adaptor to reverse the iteration through a vector using a range-based for loop:
#include <iostream>
#include <vector>
#include <ranges>
int main() {
std::vector<double> v{1, 2, 3, 4, 5};
for (auto e : v | std::views::reverse) {
std::cout << e << " ";
}
std::cout << std::endl;
}
3-way Comparison
Here’s a good discussion: https://stackoverflow.com/questions/67284403/why-should-i-use-the-three-way-comparison-operator-instead-of-the-two-way