/images/p1.jpg

Hi, I'm Tomasz

I'm a professional C++ software engineer with over a decade of hands on development experience with variety of technologies (mostly Linux & embedded systems). This is my blog.

Find me on social media

Capturing raw `this` pointer is almost always a bad idea

Lifetime problems As a reminder, I want to start with a classic example of using an invalid this captured in a lambda acting as a delegate . 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 #include <functional> #include <iostream> #include <memory> #include <string> class Item { public: explicit Item(std::string name) : name{name} {} std::function<void()> makeHelloDelegate() { return [this]{ hello(); }; } void hello() const { std::cout << "item: " << name << std::endl; } private: std::string name; }; int main() { auto item = std::make_unique<Item>("pencil"); auto d = item->makeHelloDelegate(); item.

C11 and C23 feature highlights

This is a short overview of things added along with c11 and c23 which I find useful or interesting. auto keyword… yet again auto has been repurposed in C23. Originally, it defined a storage duration for local variables (similarly as static) now, comparably as in C++, it can be used for type inference purposes. 1 2 3 4 5 6 7 void foo() { // auto is implied int i = 123; // same thing, auto keyword is redundant auto int j = 123; } In its original purpose, variables marked with auto have their storage automatically allocated and deallocated on scope entry and exit.

C++ quick tips: Concepts, type constraints and c++20 coding style

c++20 introduced concepts to the standard thanks to which now, we can specify constraints and restrictions on template parameters that a given type, variable or a function template accepts. Similarly as with e.g. virtual classes defining interfaces for a family of types through inheritance, concepts allow creating interfaces for generic code. With concepts, just by looking at the template declaration we know what to expect and what types are accepted. Having a simple template like:

Of common problems with shared pointers

There’s one repeating pattern in all C++ code bases I’ve worked with. shared_ptr is abused - one way or another. There are many reasons, sometimes people just start with shared_ptr instead of unique_ptr out of laziness, sometimes it’s the sole, default smart pointer they rely on. Often, it’s a result of many passes of refactoring and eventual quality degradation with time. This leads to all sorts of problems but there’s are definitely some repeating patterns.

#3 The state of C++ package management: The build systems

Welcome to the third and concluding part of the series about dependency and package management in C++ projects in which I’m gonna mostly focus on solutions built into build systems themselves. If you haven’t already, I encourage you to have a quick read of the first and the second part. Overview In this part I’ll have a closer look on meson wraps, cmake’s FetchContent, bazel’s central registry and, a bit unconventionally, conda.

C++20's constexpr virtual functions can simplify templates code

Recently, I’ve learned about constexpr virtual functions. The support for which was added along with C++20. C++23 additionally allows for constexpr new (with some restrictions). There’s a great article about constexpr virtual on C++ stories blog, followed by another great post about constexpr new. I highly recommend reading Bartek’s posts. Wanting to add this new feature to my tool belt I was wondering what would be the best application for constexpr virtual and how would I use them in my code.

C++ quick tips: What are conditional special member functions in C++20?

Introduction of concepts in c++20 brought along a new set of problems requiring solving related to wrapper types (like e.g. std::optional, std::variant). Specifically, special functions (like constructors, copy constructors, destructors etc) need to have the same type of traits as the type they are wrapping i.e. these have to be copyable if the underlying type is copyable, trivially copyable if the underlying types are trivially copyable, and trivially destructible if the underlying types are trivially destructible.