Better_Software_Header_Mobile Better_Software_Header_Web

Find what you need - explore our website and developer resources

The Practical Programmer’s Guide to C++20

C++20 provides C++ with even more power and expressiveness

#include <concepts>
#include <iostream>
std::integral auto factorial(std::integral auto a){ if (a <= 0) return 1;
else return a * factorial(a - 1); }
int main() {
std::cout << factorial(10) << std::endl;
return 0; }
main.cpp: In instantiation of ‘auto [requires ::Integral<<placeholder>, >] factorial(auto:11) [with auto:11 = double]:
main.cpp:50:33: required from here
main.cpp:27:30: error: use of function ‘auto [requires ::Integral<<placeholder>, >] factorial(auto:11) [with auto:11 = double]’ with unsatisfied constraints
27 | else return a * factorial(a - 1);
| main.cpp:25:15: note:
25 | Integral auto |
main.cpp:25:15: note:
main.cpp: In function ‘int main():
main.cpp:50:33: error: use of function ‘auto [requires ::Integral<<placeholder>, >] factorial(auto:11) [with auto:11 = double]’ with unsatisfied constraints
50 | std::cout << factorial(-10.5) << std::endl; |^
main.cpp:25:15: note: declared here
25 | Integral auto factorial(Integral auto a){
| ^~~~~~~~~
main.cpp:25:15: note: constraints not satisfied
main.cpp: In instantiation of ‘auto [requires ::Integral<<placeholder>, >] factorial(auto:11) [with auto:11 = double]:
main.cpp:50:33: required from here
main.cpp:8:9: required for the satisfaction of ‘Integral<auto:11>[with auto:11 = double]
main.cpp:9:26: note: the expression ‘std::is_integral<_Tp>::value [with _Tp = double]’ evaluated to ‘false9 | std::is_integral<T>::value; | ^~~~~
#include <iostream>
#include <complex>
#include <concepts>
using namespace std::complex_literals;
// while waiting for P2078 to add the is_complex type trait,
// we implement a makeshift version... template<typename T>
concept Complex = requires(T a, T b) {
        { a.imag() };
{ a.real() };
        { a + b } -> std::convertible_to<T>;
};
template<typename T>
concept Continuous = Complex<T> || std::floating_point<T>;
std::integral auto factorial(std::integral auto a){ if (a <= 0) return 1;
else return a * factorial(a - 1); }
std::floating_point auto factorial(std::floating_point auto
a){ decltype(a) one = 1.0;
return std::tgamma(a + one); }
Complex auto complexGamma(Complex auto a){
auto z = 0.0 + 0i;
// A whole mess of complex math here...
// (for one example, see https://www.johndcook.com/
blog/cpp_gamma/)
return z; }
Complex auto factorial(Complex auto a){ decltype(a) one = 1.0;
return complexGamma(a + one); }
int main() {
using namespace std::complex_literals; std::cout << factorial(10) << std::endl; std::cout << factorial(-10.5) << std::endl; std::cout << factorial(10.0 + 2i) << std::endl; return 0;
}
using namespace std::complex_literals;
// Definition #1 – handles floating types only
void f(std::floating_point auto x);
// Definition #2 – handles floats and complex numbers
void f(Continuous auto x);
int main() { f(3.14f);
compiler calls f #1
    f(0.7070.707i);
compiler calls f #2
return 0; }
#include <ranges>
#include <iostream>
int main()
{
auto ints = std::ranges::iota_view{1, 33};
32 is last
// Half-closed range,
auto even_bytes = [](int i) { return (i % 8)==0; };
boundaries
// Keep only the byte
}; auto largest_value = [](int i) { return (1ULL<<i)-1; unsigned // Biggest expressible
for (uint64_t i : ints | std::views::filter(even_bytes) |
value)) {             std::views::transform(largest_
    }   std::cout << i << ‘ ‘;
    std::cout << std::endl;
}
255 65535 16777215 4294967295
#include <iostream>
#include <vector>
#include <range/v3/view.hpp>
#include <range/v3/action.hpp>
#include <range/v3/view/istream.hpp>
#include <range/v3/range/conversion.hpp>
using namespace ranges;
auto string_to_lower(const std::string &s) { return s | views::transform(tolower) |
to<std::string>;
}
auto string_only_alnum(const std::string &s) {
return s | views::filter(isalnum) | to<std::string>; }
bool string_is_empty(const std::string &s) {
return s.empty(); }
int main(int argc, char *argv[])
{
const int n = argc <= 1
                    ? 10
                    : atoi(argv[1]);
const auto words = istream_range<std::string>(std::cin)
| views::transform(string_to_lower)
| views::transform(string_only_alnum)
           | views::remove_if(string_is_empty)
           | to_vector | actions::sort;
const auto frequency = words
| views::group_by(std::equal_to{})
| views::transform([] (const auto &group) {
distance(group);
*cbegin(group);
const auto size =
const std::string word =
return std::pair{size, word}; })
| to_vector | actions::sort;
for (auto [count, word]: frequency | views::reverse
                                       | views::take(n)
){
std::cout << count << “ “ << word << ‘\n’;
}
return 0; }
// Note: the standard library isn’t yet module-ready in
C++20,
// so this example won’t compile. If it was, it might look
like this:
import <iostream>; int main()
{
}
std::cout << “Hello module world!\n”;
// simplelib.cpp
export module simple.example;
// dots can be optionally inserted for module
name readability
export void foo(){} // foo() is accessible by outside world
void bar(){} // bar() is only visible within this file
generator<int> iota(int n = 0) { while(true)
    co_yield n++;
}
task<> tcp_echo_server() { char data[1024];
for (;;) {
    size_t n = co_await socket.async_read_
some(buffer(data));
} } co_await async
std::cout << std::format({1}, {0}!\n”, “world”, “hello”);
std::cout << std::format(“he{0}{0}o, {1}!\n”, “l”,
“world”);
#include <compare>
#include <iostream>
class ExValue { public:
constexpr explicit ExValue(int val): value{val} { } auto operator<=>(const ExValue& rhs) const = default; constexpr auto operator<=>(const int& rhs) const {
return value - rhs; }
private:
int value; };
template<typename A, typename B> const auto whatis(A a, B b) {
auto comparison = (a <=> b); if (comparison < 0)
return “less”;
else if (comparison > 0) elsereturn “greater”;
}
return “equals”;
int main() {
std::cout << whatis(ExValue(10), ExValue(12)) << std::endl; std::cout << whatis(ExValue(12), ExValue(10)) << std::endl; std::cout << whatis(ExValue(8), ExValue(8)) << std::endl; std::cout << whatis(10, ExValue(12)) << std::endl; std::cout << whatis(100, ExValue(50)) << std::endl; std::cout << whatis(ExValue(10), 40) << std::endl; std::cout << whatis(ExValue(40), 10) << std::endl;
std::cout << (bool) (ExValue(10) < ExValue(15)) << std::endl; std::cout << (bool) (ExValue(10) > ExValue(15)) << std::endl; std::cout << (bool) (ExValue(10) <= ExValue(15)) << std::endl; std::cout << (bool) (ExValue(10) >= ExValue(15)) << std::endl; std::cout << (bool) (ExValue(10) == ExValue(15)) << std::endl; std::cout << (bool) (ExValue(10) != ExValue(15)) << std::endl;
}

Tags:

c++
Giuseppe D'Angelo and Ivan Cukic