C++ recipes

Operating over a whole container using ranges (C++20) #include <vector>#include <algorithm>#include <random>#include <iostream> int main() { const auto printy = [](const auto &vec){ for (size_t i = 0; const auto&v : vec) std::cout << v << (++i == vec.size() ? "\n" : " "); }; std::vector<int> v(4); printy(v); std::ranges::fill(v, -1); printy(v); std::ranges::generate(v, std::rand); printy(v); } Generates: 0 0 0 0 -1 -1 -1 -1 1804289383 846930886 1681692777 1714636915 https://godbolt.org/z/31196Kz5z Zip two containers #include <iostream>#include <vector>#include <algorithm>#include <ranges> int main() { const std::vector<int> a{1, 2, 3}; const std::vector<int> b{4, 5, 6}; std::vector<std::pair<int, int>> zipped; zipped. [Read More]

GDB

Debugger crib sheet

Adding debug symbols gcc -g hello.c gdb a.out # Run program run # Run and immediately break start # View code at current break point list # Break main b main # Break at line 9 b 9 TUI mode - text user interface Type ctrl-X A ctrl L - repaint ctrl X2 - multiple windows ctrl X2 - view registers tui reg float - view floating registers ctrl x 1 - source code view ctrl p/n - command history Python interpreter built in (since version 7) import os print(os. [Read More]

Travis CI

Configuration for C++, Python, R, bash and Graphviz

Note: my use of Travis CI has been superseded by GitLab which has all this built in. In fact this blog is generated by GitLab. Create an account with your GitHub login and enable a repo to get started. (Travis Pro appears to enable new repos by default.) Simple C++11 compilations If you just want to get something building quickly the default Trusty build has clang 5 pre-installed, no need for complicated matrices. [Read More]

Exceptions in destructors

In C++11 destructors default to noexcept so you have to go out of your way to make them throw. See throwing exceptions in a destructor. You can throw an exception in a destructor, but that exception must not leave the destructor; if a destructor exits by emitting an exception, all kinds of bad things are likely to happen because the basic rules of the standard library and the language itself will be violated. [Read More]

STL containers

Containers replicate structures very commonly used in programming: dynamic arrays (vector), queues (queue), stacks (stack), heaps (priority_queue), linked lists (list), trees (set), associative arrays (map)… http://www.cplusplus.com/reference/stl/ Sequence containers vector list deque array forward_list Modifying a vector potentially invalidates all existing iterators. And inserting an element can cause the whole container to be reallocated (here be dragons!) deque is not guaranteed to store all its elements in contiguous storage locations but has efficient insertion and deletion of elements at the beginning and end of a sequence. [Read More]

Preparing for a C++ interview

As a senior software engineer

The Amazon tech interview topics is a great guide to whet your appetite. Know your language standards, algorithms and data structures. Be comfortable calculating and discussing the complexity of your solutions (Big O notation). What’s the difference between symmetric and asymmetric encryption? Get some side projects on GitLab to talk about at interviews and run/deploy them as a daily cron job. Be aware that recruiters may remove any contact details in your CV – including URLs with your coding projects – so be sure to obfuscate them. [Read More]

ADL

Argument dependent lookup

Why does this compile? A one-liner to print a vector to stdout. But why does this compile without the namespace std::? #include <iostream>#include <vector>#include <iterator> int main() { const std::vector<int> v{1, 2, 3, 4, 5}; copy(cbegin(v), cend(v), std::ostream_iterator<int>(std::cout, "\n")); } Run the code on Compiler Explorer, Jason Turner on YouTube and ADL on Wikipedia. Note: C++14 is the default for the latest GCC (9.2). Exercise Propose some other examples of ADL. [Read More]

Modern C++

Modules (C++20) “Modules are orthogonal to namespaces.” lvalues and rvalues An lvalue refers to an object that persists beyond a single expression. You can think of an lvalue as an object that has a name. All variables, including nonmodifiable (const) variables, are lvalues. An rvalue is a temporary value that does not persist beyond the expression that uses it. A function call can be an lvalue if and only if the return value is a reference. [Read More]

KEYnote

A Linux JUCE application that extracts the peak FTT bin from a live audio recording and reports the closest note

Screenshot is highlighting the major 3rd of an A chord: 440, 550 and 660Hz. Note the FFT bin is not a precise pitch so the closest concert pitch is displayed. See the source on GitHub. Note mapping #include <iostream>#include <map>#include <vector> const std::map<double, std::string> notes{ // Catch all for lower bound search {0.0, "Bx"}, // All the notes we're interested in. At the low end a single Fourier bin // will map to multiple notes. [Read More]

How does your vector grow?

How many times is the destructor for the “fax” class called below after populating a five element STL vector? std::vector<fax> y; for (size_t i = 0; i < 5; ++i) y.push_back(fax()); Remarkably it’s 17 times! https://godbolt.org/z/vd8GGV For each push we call the default constructor to create a transient object and then call the copy constructor to populate the new element with its data. So far so good. But crucially when the vector is resized we must also copy all the existing elements into the new container, resulting in an unexpected growth. [Read More]