Articles & Books

Don't automatically use auto parameters in C++ -- Lesley Lai

Should we use almost always auto parameters?

Don't automatically use auto parameters in C++

by Lesley Lai

From the article:

Since C++14, we can create lambda expressions that take auto parameters. C++20 generalizes this idea by allowing us to do the same thing for regular functions. With this feature's advent, the programming style where all parameters are auto becomes popular among some C++ programmers. However, I think we should not use it if we had to. The more specific the type of the parameter is, the better.

How C++ Resolves a Function Call--Jeff Preshing

Know everything about it.

How C++ Resolves a Function Call

by Jeff Preshing

from the article:

C is a simple language. You’re only allowed to have one function with each name. C++, on the other hand, gives you much more flexibility:

  • You can have multiple functions with the same name (overloading).
  • You can overload built-in operators like + and ==.
  • You can write function templates.
  • Namespaces help you avoid naming conflicts.

I like these C++ features. With these features, you can make str1 + str2 return the concatenation of two strings. You can have a pair of 2D points, and another pair of 3D points, and overload dot(a, b) to work with either type. You can have a bunch of array-like classes and write a single sort function template that works with all of them.

But when you take advantage of these features, it’s easy to push things too far. At some point, the compiler might unexpectedly reject your code with errors like:

error C2666: 'String::operator ==': 2 overloads have similar conversions
note: could be 'bool String::operator ==(const String &) const'
note: or       'built-in C++ operator==(const char *, const char *)'
note: while trying to match the argument list '(const String, const char *)'

Like many C++ programmers, I’ve struggled with such errors throughout my career. Each time it happened, I would usually scratch my head, search online for a better understanding, then change the code until it compiled. But more recently, while developing a new runtime library for Plywood, I was thwarted by such errors over and over again. It became clear that despite all my previous experience with C++, something was missing from my understanding and I didn’t know what it was.

Fortunately, it’s now 2021 and information about C++ is more comprehensive than ever. Thanks especially to cppreference.com, I now know what was missing from my understanding: a clear picture of the hidden algorithm that runs for every function call at compile time.

Creating other types of synchronization objects that can be used with co_await, part 6--Raymond Chen

The series continue.

Creating other types of synchronization objects that can be used with co_await, part 6

by Raymond Chen

From the article:

Our next stop in showing off our library for building awaitable synchronization objects is the semaphore. This will look very familiar because a semaphore with a maximum token count of 1 is the same thing as an auto-reset event, so we can just extend our auto-reset event implementation to support multiple tokens...

Non-Terminal Variadic Parameters and Default Values--Bartlomiej Filipek

How to best use source_location?

Non-Terminal Variadic Parameters and Default Values

by Bartlomiej Filipek

From the article:

Currently, as of C++20, there’s no support for so called non-terminal variadic arguments. For example, we cannot write:

template <class ...Args> void func(Args&& ...args, int num=42);
func(10, 20); // error

As you can see, I wanted 10 and 20 to be passed as ...args and 42 as a default value for num. Compilers currently cannot resolve this code.

In this blog post, I’d like to show you a couple of tricks you can implement to avoid this issue. Knowing those techniques might help with things like logging functions where we could have std::source_location at the end of a function declaration...

Creating other types of synchronization objects that can be used with co_await, part 4--Raymond Chen

The series continue.

Creating other types of synchronization objects that can be used with co_await, part 4

by Raymond Chen

From the article:

Now that we’ve finished our library for building awaitable synchronization objects, let’s actually use it.

The introduction to this part of the series began with a demonstrate of a one-shot event. So let’s take it a step further and make it a resettable event...

C++ Fold Expressions 101--Jonathan Boccara

Back to the basics.

C++ Fold Expressions 101

by Jonathan Boccara

From the article:

C++17 brought fold expressions to the language. This interesting feature allows to write expressive code, that almost seems magical.

Here is a two-posts recap on how fold expressions work (this post) and how they can improve your code (the next post).

How to use C++ for Cross-Platform Development--Gusts Kaksis

Code once, deploy everywhere.

How to use C++ for Cross-Platform Development

by Gusts Kaksis

From the article:

My current line of work revolves around an app that runs on four platforms – Android, iOS, macOS and Windows. It’s core code base is written in C++ and it uses Objective-C (on iOS and macOS) and Java (on Android) to access native APIs. I wanted to share some tips and tricks that I’ve accumulated over time on how to make the ends meet.

This article will mainly concentrate on languages and so called backend part of the application, if you are also interested in cross-platform UI development, then that is a whole another story and I won’t be covering it here. I can only mention some good frameworks to start with, like Qt, React Native, Flutter to name a few (the latter two being further away from C++, but they have C++ bindings)...