8000 GitHub - chaithanya1996/moderncpp: Modern C++: Snippets and Examples
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

chaithanya1996/moderncpp

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Modern C++: Snippets and Examples

GitHub Pages with snippets for Modern C++


  • We often need to copy and paste some snippets to code more productively.
  • Snippets can help us when it's not easy to remember all high levels features Modern C++ has to offer.
  • This repository contains lots of organized, reusable, and safe snippets for Modern C++.
  • All snippets are available in GitHub pages in a convenient way for copying and pasting.


Facebook QZone Weibo Reddit Twitter LinkedIn WhatsApp Line.me Telegram.me HackerNews


Table of Contents

Quick Start

How this repository works

This is how this repository works:

  • The snippets directory has lots of short programs with useful C++20 snippets
  • The examples directory has lots of short tasks using these snippets
  • GitHub actions ensures all snippets are working on GCC, MSVC, and Clang
  • We generate GitHub pages with all snippets by groups of tasks using mkdocs material and mdsplit

Libraries

We give preference to libraries in this order:

  1. Libraries supported by most C++ compilers
  2. Libraries accepted into the C++ standard
  3. Libraries likely to be accepted into the next C++ standard
  4. Libraries representative of existing practice

External Libraries

For external libraries, we also include a short CMake snippet in the build script with:

  • find_package to find, setup, and link the large external libraries
  • FetchContents to download, build, and link the external library

Snippets and Examples

The snippets, as they are, might seem like they are examples in the sense that they are in long files sometimes. What makes them snippets is that, at the source file level, they represent lots of independent short tasks separated by comments. Unlike in the examples, the tasks separated by comments are unrelated. You can just copy and paste the snippets between pairs of comments.


GitHub Pages

We generate GitHub pages with all snippets:

  • The GitHub pages are generated with mkdocs material and mdsplit
  • Snippets organized are categorized by groups of tasks
  • Sections are easy to explore, copy, and paste

Why Modern C++

Why use C++

C++ has always been a great language for Scientific Computing, High-Performance Computing, and Data Analysis:

  • Most programmers are familiar with its basic syntax;
  • It's been among the most popular languages over last 40 years;
  • Access to hundreds of thousands of high-performance libraries;
  • Performance level almost no other language can achieve;
  • Complex abstractions with zero-overhead;
  • Easy access to parallelism;
  • Numerous compilers with great optimization options available;
  • Innumerable target platforms, from microcontrollers, to GPUs, to mobile, to webassembly;
  • Does not rely on any virtual machine;
  • Easy bindings from/to virtually any other programming language (Python, Javascript, PHP, R, Java, Matlab, Rust, Swift, Julia, C, ... you name it);
  • Great tools for static analysis to avoid bugs;
  • Avoids the two-languages problem in scientific computing: one for prototyping and one to reimplement all the work once the experiments are successful;
  • No need for special licenses to distribute your compiled code, like it is common in technical languages that rely on virtual machines;
  • Allows saving tons of money and extra-security for applications to be run in the cloud or dedicated servers.

Why use Modern C++

Many people have move from C++ over the last decade and might not be aware that the Modern C++ ecosystem has evolved to cover almost all use cases that made C++ inconvenient for certain tasks in the past:

By incentivizing and highlighting modern C++ features in instructional content, it's also possible to combine the familiar syntax of C and old C++ to achieve high levels of abstraction with a gentle learning curve.

Installing C++20

Linux / GCC

Many operating systems don't come with a C++20 compiler by default. Follow these instructions to install C++20.

Update GCC:

sudo apt install build-essential
sudo add-apt-repository ppa:ubuntu-toolchain-r/test
sudo apt-get update
sudo apt install gcc-10
sudo apt install g++-10
sudo update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-10 10
sudo update-alternatives --install /usr/bin/g++ g++ /usr/bin/g++-10 10

Set your default compiler with:

update-alternatives --config g++

Mac OS / Clang

Many operating systems don't come with a C++20 compiler by default. Follow these instructions to install C++20.

Download a recent version of Clang.

curl --output clang.tar.xz -L https://github.com/llvm/llvm-project/releases/download/llvmorg-11.0.0/clang+llvm-11.0.0-x86_64-apple-darwin.tar.xz
mkdir clang
tar -xvJf clang.tar.xz -C clang

Copy the files to usr/local/:

cd clang/clang+llvm-11.0.0-x86_64-apple-darwin
sudo cp -R * /usr/local/

Let CMake know that's the compiler you want to use.

If you want this to be your default compiler, you can set the CXX environment variable:

export CXX=/usr/local/bin/clang++

If you want to use this compiler in a single project, run CMake with these options:

-DCMAKE_C_COMPILER=/usr/local/bin/clang -DCMAKE_CXX_COMPILER=/usr/local/bin/clang++

Or tell you IDE to pass these options to CMake:

Windows / MSVC

Many operating systems don't come with a C++20 compiler by default. Follow these instructions to install C++20.

Update your Visual Studio Compiler.

The most recent version of Visual Studio should include C++20.

!!! warning "Help wanted" We still don't know of a script for installing C++20 on Windows from the terminal.

This would be especially useful for our [build workflow](./.github/workflows/build.yml), which has not been testing MSVC since we moved to C++20.

Please let us know or open a PR if you know of such a script.

WebAssembly / Emscripten

If you are programming for the web, a common option for C++ and WebAssembly is emscripten.

You can install emscripten from most package managers for Windows, Linux, or Mac OS. You can also follow the instructions on their website to build from source.

Then follow these instructions to compile your first "Hello World!" for the web. Your C++ program will become this beautiful webpage:

Interpreter / Cling

If you are using C++ for scientific computing or learning C++, it's often useful to have a C++ interpreter for short experiments.

You can install Cling from most package managers for Linux or Mac OS. You can also follow the instructions on their website to download the binaries or build it from source.

Although you can use cling directly, it is much more convenient to use the interpreter as a Jupyter notebook kernel. You can follow these instructions to install Jupyter Lab, and these instructions to install the xeus-cling kernel.

This creates a beautiful environment for playing with C++ interactively:

IDEs

These are the most common IDEs and text editors most commonly used for C++ programming:

IDE or Text Editor Users Notes
Visual Studio 28% Windows
Vim 17% (Text Editor)
Qt Creator 12% Best for Qt Users
Visual Studio Code 10%
CLion 9%
Emacs 7% (Text Editor)
Xcode 4% Mac OS
Eclipse 4%
Others 9%

!!! warning These numbers are constantly changing.

Basic Syntax

Input / Output

Build script

--8<-- "snippets/input_output/CMakeLists.txt"

Hello World

--8<-- "snippets/input_output/hello_world.cpp"

Input

--8<-- "snippets/input_output/cin.cpp"

Output

--8<-- "snippets/input_output/printing.cpp"

Related examples:

!!! info "Some people told me std::endl is evil. Is that true?"

The reason people say that is because std::endl costs more than `'\n'`. But it costs more because it does not do the same thing. It exists for a reason. There are [some situations](https://en.cppreference.com/w/cpp/io/manip/flush) where it makes sense to flush the stream.

On the other hand, some people will simply say `std::endl` is evil, but this is a little misleading. They are usually generalizing from benchmarks that explore specific edge cases to prove a point. These benchmarks are usually meant to show the difference between `'\n'` and `std::endl` and not as proof that `std::endl` is evil per se, or significantly more expensive than `'\n'` in all possible use cases.

In the end, I can't tell which is always better because they do different things. But I can tell you their differences and their cost. So here are some differences:

* The definitions:

    * The buffer: The streams usually store the data in a buffer, which is meant to make things more efficient. The buffer reduces the number of trips to their final destination.

    * Flushing: Once the buffer is full, then the data goes to its final destination, which is usually the console or a file. For convenience, when that happens, we say the stream is flushing the buffer.

    * Commands: C++ gives you the option to flush what is in the buffer immediately or you might wait for the stream to flush automatically according to some internal heuristic.

    * Automatically flushing: This heuristic is usually when the buffer is full, or when the buffer is about to be destructed. Sometimes, it flushes automatically when it sees a new line. That depends on the kind of stream.

* What the commands mean: Flushing does have a semantic meaning different from `'\n'`, and this might be a good convention for some pieces of code, especially when you want to make sure you will see the output immediately. Particularly for `std::cout`:
    * `'\n'` means "put a newline in the buffer"
    * `std::flush` means "show me what's in the buffer now"
    * `std::endl` means "put a newline in the buffer and then show me what's in the buffer now"
* Their cost: By the definition above, std::endl logically costs more than `'\n'` because it's doing what `'\n'` does plus one more thing. Some people often use examples and benchmarks flushing files often as evidence that `std::endl` is evil per se. But there's a catch here:
    * There's very little reason to flush to files because we don't usually care if the data gets in the file a little later.
    * Flushing to files is much more comparatively expensive than flushing to `std::cout`.
    * If you benchmark this difference, you will see the time difference of flushing std::cout to the console (not files!) is negligible:
        * *GCC -O2: Flush: 2.32234e-06 / Don't Flush: 2.26303e-06*
        * *Clang -O2: Flush: 2.33343e-06 / Don't Flush: 2.23031e-06*
    * Besides this small difference flushing to console is much more likely to be useful than flushing to a file.
    * Also, this difference is almost certainly even smaller in a real application. Almost no application is spending more time flushing than calculating things to flush. Unless it's a flushing benchmark like the one above.

In the end, flushing to a file is almost always a bad idea. Flushing to the console won't probably have any significant impact. In that second case, if not flushing can cause you any problems, just flush.

Format

--8<-- "snippets/input_output/format.cpp"

Tabulate

--8<-- "snippets/input_output/tabulate.cpp"

!!! note While this library is not very representative of existing practice, we use it in lots of examples to report results. An alternative could be snippets with std::setw and std::setfill to manually create tables.

Control flow

Build script

--8<-- "snippets/control_flow/CMakeLists.txt"

Sequential

--8<-- "snippets/control_flow/sequential.cpp"

Conditional

--8<-- "snippets/control_flow/conditional.cpp"

Loops

--8<-- "snippets/control_flow/loops.cpp"

Examples:

examples/control_flow/calculator.cpp

Scopes

--8<-- "snippets/control_flow/scopes.cpp"

Data types

Build script

--8<-- "snippets/data_types/CMakeLists.txt"

Fundamental Data Types

--8<-- "snippets/data_types/data_types.cpp"

Operators

--8<-- "snippets/data_types/operators.cpp"

Auto

--8<-- "snippets/data_types/auto.cpp"

Constants

--8<-- "snippets/data_types/constants.cpp"

Basic Data Types

Build script

--8<-- "snippets/basic_types/CMakeLists.txt"

Raw arrays

--8<-- "snippets/basic_types/raw_arrays.cpp"

Arrays

--8<-- "snippets/basic_types/arrays.cpp"

Vectors

--8<-- "snippets/basic_types/vectors.cpp"

Strings

--8<-- "snippets/basic_types/strings.cpp"

Move

--8<-- "snippets/basic_types/move.cpp"

Aggregate initialization

--8<-- "snippets/basic_types/aggregate_initialization.cpp"

Structured binding

--8<-- "snippets/basic_types/structured_binding.cpp"

Pointers

Build script

--8<-- "snippets/pointers/CMakeLists.txt"

Address Operator

--8<-- "snippets/pointers/address_operator.cpp"

Raw pointers

--8<-- "snippets/pointers/raw_pointers.cpp"

References

--8<-- "snippets/pointers/references.cpp"

Smart pointers

--8<-- "snippets/pointers/smart_pointers.cpp"

Functions

Build script

--8<-- "snippets/functions/CMakeLists.txt"

Function

!!! warning These snippets are about the syntax for creating functions. They are not about how to achieve the tasks in these functions. The tasks are just placeholders and the C++ STL already provides much better alternatives for most of these algorithms.

--8<-- "snippets/functions/functions.cpp"

Related examples:

Lambda

--8<-- "snippets/functions/lambda.cpp"

Files

Build script

--8<-- "snippets/files/CMakeLists.txt"

FindFilesystem.cmake:

--8<-- "cmake/FindFilesystem.cmake"

File streams

--8<-- "snippets/files/files.cpp"

Filesystem

--8<-- "snippets/files/filesystem.cpp"

Algorithms / Data Structures

Date and time

Build script

--8<-- "snippets/datetime/CMakeLists.txt"

Clock

--8<-- "snippets/datetime/clock.cpp"

Related examples:

Datetime

--8<-- "snippets/datetime/datetime.cpp"

Random

Build script

--8<-- "snippets/random/CMakeLists.txt"

Random

--8<-- "snippets/random/random.cpp"

PCG

--8<-- "snippets/random/pcg.cpp"

Template

Build script

--8<-- "snippets/templates/CMakeLists.txt"

Template function

--8<-- "snippets/templates/template_functions.cpp"

Template aliases

--8<-- "snippets/templates/template_alias.cpp"

Concepts

--8<-- "snippets/templates/concepts.cpp"

FindConcepts.cmake:

--8<-- "cmake/FindConcepts.cmake"

SFINAE

--8<-- "snippets/templates/sfinae.cpp"

Algorithm

Build script

--8<-- "snippets/algorithm/CMakeLists.txt"

Searching

!!! hint

The standard [algorithms](#basic-algorithms) for searching elements in a container are:

* `std::find` for linear search
* `std::lower_bound` and `std::upper_bound` for binary search

These snippets include extra functions describing how these algorithms can be implemented. They are mostly relevant for people studying these algorithms for the first time. 
--8<-- "snippets/algorithm/searching.cpp"

Sorting

!!! hint

The standard [algorithms](#basic-algorithms) for sorting containers are `std::sort` and `std::stable_sort`.

These snippets include extra functions describing how these tasks can be implemented with many other classic sorting algorithms. They are mostly relevant for people studying sorting algorithms for the first time.
--8<-- "snippets/algorithm/sorting.cpp"

Basic Algorithms

--8<-- "snippets/algorithm/algorithms.cpp"

Ranges

--8<-- "snippets/algorithm/ranges.cpp"

Data structures

Build script

--8<-- "snippets/data_structures/CMakeLists.txt"

Sequential Containers

--8<-- "snippets/data_structures/sequential_containers.cpp"

Associative Containers

--8<-- "snippets/data_structures/associative_containers.cpp"

Memory resource

--8<-- "snippets/data_structures/memory_resource.cpp"

FindPMR.cmake:

--8<-- "cmake/FindPMR.cmake"

!!! warning "PMR"

Not all compilers implement PMR yet, even though it's a C++17 feature. We need the CMake script [`FindPMR.cmake`](cmake/FindPMR.cmake) to identify if your compiler implements it. 

Span

--8<-- "snippets/data_structures/span.cpp"

Bitset

--8<-- "snippets/data_structures/bitset.cpp"

Spatial Containers

--8<-- "snippets/data_structures/spatial_containers.cpp"

Heterogeneous Types

Build script

--8<-- "snippets/heterogeneous_types/CMakeLists.txt"

Tuples

--8<-- "snippets/heterogeneous_types/tuples.cpp"

Any

--8<-- "snippets/heterogeneous_types/any.cpp"

Optional

--8<-- "snippets/heterogeneous_types/optional.cpp"

Variant

--8<-- "snippets/heterogeneous_types/variant.cpp"

Programming Paradigms

Basic Paradigms

Build script

--8<-- "snippets/paradigms/CMakeLists.txt"

Polymorphism

--8<-- "snippets/paradigms/polymorphism.cpp"

Shared from this

--8<-- "snippets/paradigms/shared_from_this.cpp"

Metaprogramming

--8<-- "snippets/paradigms/metaprogramming.cpp"

CRTP

--8<-- "snippets/paradigms/CRTP.cpp"

SFINAE

--8<-- "snippets/paradigms/SFINAE.cpp"

Parallelism

Build script

--8<-- "snippets/parallel/CMakeLists.txt"

Execution Policies

--8<-- "snippets/parallel/policies.cpp"

!!! warning "Help wanted" Clang requires a CMake script to link TBB with this target to make this work.

Threads

--8<-- "snippets/parallel/multithreading.cpp"

Executors

--8<-- "snippets/parallel/executors.cpp"

Timers

--8<-- "snippets/parallel/timers.cpp"

Signals

--8<-- "snippets/parallel/signals.cpp"

Async++

--8<-- "snippets/parallel/async_pools.cpp"

Utilities

Regular Expressions

Build script

--8<-- "snippets/utilities/CMakeLists.txt"

Regex

--8<-- "snippets/utilities/regex.cpp"

Networking

Build script

--8<-- "snippets/networking/CMakeLists.txt"

Network

--8<-- "snippets/networking/network.cpp"

Async Network

--8<-- "snippets/networking/network_async.cpp"

Http server

main.cpp

--8<-- "snippets/networking/server/main.cpp"

server.hpp

--8<-- "snippets/networking/server/server.hpp"

connection_manager.hpp

--8<-- "snippets/networking/server/connection_manager.hpp"

connection.hpp

--8<-- "snippets/networking/server/connection.hpp"

header.hpp

--8<-- "snippets/networking/server/header.hpp"

reply.hpp

--8<-- "snippets/networking/server/reply.hpp"

request.hpp

--8<-- "snippets/networking/server/request.hpp"

request_parser.hpp

--8<-- "snippets/networking/server/request_parser.hpp"

mime_types.hpp

--8<-- "snippets/networking/server/mime_types.hpp"

request_handler.hpp

--8<-- "snippets/networking/server/request_handler.hpp"

mime_types.cpp

--8<-- "snippets/networking/server/mime_types.cpp"

request_parser.cpp

--8<-- "snippets/networking/server/request_parser.cpp"

reply.cpp

--8<-- "snippets/networking/server/reply.cpp"

request_handler.cpp

--8<-- "snippets/networking/server/request_handler.cpp"

connection.cpp

--8<-- "snippets/networking/server/connection.cpp"

connection_manager.cpp

--8<-- "snippets/networking/server/connection_manager.cpp"

server.cpp

--8<-- "snippets/networking/server/server.cpp"

GUIs

Build script

--8<-- "snippets/gui/CMakeLists.txt"

Qt

--8<-- "snippets/gui/qt/qt_hello.cpp"

Build script:

--8<-- "snippets/gui/qt/CMakeLists.txt"

OpenGL + SDL

--8<-- "snippets/gui/opengl/sdl/sdl_hello.cpp"

Build script:

--8<-- "snippets/gui/opengl/sdl/CMakeLists.txt"

OpenGL + GLFW

--8<-- "snippets/gui/opengl/glfw/opengl_hello.cpp"

Build script:

--8<-- "snippets/gui/opengl/glfw/CMakeLists.txt"

IMGUI

--8<-- "snippets/gui/imgui/imgui_hello.cpp"

Build script:

--8<-- "snippets/gui/imgui/CMakeLists.txt"

Webview

--8<-- "snippets/gui/webview/webview_hello.cpp"

Build script:

--8<-- "snippets/gui/webview/CMakeLists.txt"

System tray

--8<-- "snippets/gui/tray/tray_hello.cpp"

Build script:

--8<-- "snippets/gui/tray/CMakeLists.txt"

Testing

Build script

--8<-- "snippets/tests/CMakeLists.txt"

Catch2

--8<-- "snippets/tests/unit_tests_catch.cpp"

boost.ut

--8<-- "snippets/tests/unit_tests_ut.cpp"

Source Location

--8<-- "snippets/tests/source_location.cpp"

Plots

--8<-- "snippets/tests/plots.cpp"

CMake Functions

Project Flags

--8<-- "cmake/functions/project_flags.cmake"

Target Options

--8<-- "cmake/functions/target_options.cmake"

Sanitizers

--8<-- "cmake/functions/sanitizers.cmake"

Qt Helpers

--8<-- "cmake/functions/qt_helpers.cmake"

FAQ

Where are the examples? Are the snippets examples?

The complete examples are in the examples directory, but they not explicitly replicated in the docs because they are much longer than the snippets.


What's the difference between snippets and examples?

Examples are often long and don't represent independent tasks you can copy and paste. Snippets represent independent tasks between pairs of comments that you can copy and paste.


Shouldn't the snippet files be short files?

The snippets could go into a new category level and we could separate them at their lowest level by file, but that would make them difficult to explore if the resolution is too high, like 3-4 lines of code per file. Also, because snippets have pre-conditions and post-conditions, it would make it much harder to test all snippets.


Why not get my snippets directly from cppreference or cplusplus.com?

The cppreference is not meant for snippets and this repository is not meant to be a reference for the C++ standard. Some implications are:

  • The snippets:
    • Meant to list the commands you most often need in a library.
    • Lots of independent tasks for copying and pasting
    • Include corresponding build scripts when something more complex is required
    • Include external libraries when it's existing practice
    • Organized roughly in the order someone learning C++ might need them
  • The examples in cppreference or cplusplus.com:
    • Meant to make points about the internals of the libraries.
    • A single task meant to prove a point
    • Has nothing to do with build scripts
    • Has nothing to do with external libraries
    • Mix simple and complex concepts to make a point

Why do you use std::endl so much in the snippets? Isn't it evil?

The snippets usually use std::endl instead of '\n':

  • Flushing does have a semantic meaning different from '\n which is a nice convention for small snippets (please show me what's in the buffer vs. put a newline in the buffer)
  • Most snippets require creating variables first and using them later so that we can test the snippets with GitHub Actions. The flushing part is not what you are going to copy and paste in a snippet.
  • The time difference of flushing std::cout to the console (not files!) is negligible
  • Almost no application is spending more time flushing than calculating things to flush. Unless it's a flushing benchmark.

Get involved

  • After getting started with this library, please complete this survey to let us know how we can improve your experience.
  • Discussions are concentrated on our GitHub discussions page. Don't refrain from asking questions and proposing ideas.
  • If you are a programmer with good ideas, please share these ideas with us.
  • Academic collaboration is more than welcome.

Contributing

Feel free to contribute with new snippets to this repository. For complex features and changes, consider getting feedback from the community first.

There are many ways in which you can contribute to this library:

  • Testing the library in new environments
  • Contributing with interesting snippets and examples
  • Finding problems in the documentation
  • Finding bugs in general
  • Whatever idea seems interesting to you

The only thing we ask you is to make sure your contribution is not destructive. Some contributions in which we are not interested are:

  • "I don't like this optional feature so I removed/deprecated it"
  • "I removed this feature to support older versions of C++" but have not provided an equivalent alternative. This repository is focused on Modern C++.
  • "I removed this feature so I don't have to install/update ______" but have not provided an equivalent alternative
  • "I'm creating this high-cost promise that we'll support ________ forever" but I'm not sticking around to keep that promise

In doubt, please open a discussion first.


Guidelines

If contributing with code, please leave the pedantic mode ON (-DBUILD_WITH_PEDANTIC_WARNINGS=ON), use cppcheck, and clang-format.

Example: CLion

CLion Settings with Pedantic Mode

If contributing to the documentation, please edit README.md directly, as the files in this documentation are automatically generated with mdsplit.

About

Modern C++: Snippets and Examples

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 81.5%
  • CMake 18.5%
0