Welcome to the next pikoTutorial!
What are C++ literals?
Literals in C++ are constant values directly embedded into the code, such as numbers, characters and strings. They represent fundamental data, making the code more readable and expressive. C++ provides several built-in literals, like integer literals (42), floating-point literals (3.14), and string literals (“Hello”). However, C++ also allows developers to define custom literals, enabling more readable and type-safe expressions tailored to specific needs.
For example, consider the use of the standard chrono literals for handling time durations:
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::literals::chrono_literals;
int main() {
auto duration = 500ms;
std::this_thread::sleep_for(duration);
std::cout << "Waiting for " << duration.count() << "ms done!";
}Here, the 500ms literal is much more readable than simply writing 500, as it explicitly conveys that the value represents milliseconds. This type-safe approach prevents errors by associating units directly with values, making the code both easier to understand and less prone to mistakes.
But that’s not all – because the duration value is not just a number, but a dedicated type std::chrono::milliseconds, we can overload a stream operator for this specific type. The benefit of such approach is that user no longer needs to call duration.count() and add string “ms” after during the printing. Variable duration can be used directly:
#include <chrono>
#include <iostream>
#include <thread>
using namespace std::literals::chrono_literals;
std::ostream& operator<<(std::ostream& stream, std::chrono::milliseconds value)
{
return stream << value.count() << "ms";
}
int main() {
auto duration = 500ms;
std::this_thread::sleep_for(duration);
std::cout << "Waiting for " << duration << " done!";
}This produces the following output:
Waiting for 500ms done!Defining custom literals
Standard C++ literals are useful, but you may want to define your own, custom ones. Custom literals are defined using operator overloading combined with a literal, which is typically preceded by an underscore:
ReturnType operator "" _literal(ParameterType parameter);Although the underscore prefix is not mandatory, it is highly recommended. Names without an underscore will generate a compiler warning that such identifiers are reserved for future standardization. The underscore ensures that your custom literal does not conflict with existing or future literals in the standard library.
Example of custom literal usage
Below you can find an example showing how to define your custom literal dedicated for byte strings which are supposed to be stored in a vector of bytes.
#include <iostream>
#include <vector>
// define custom literal
std::vector<uint8_t> operator "" _B(const char* input, size_t) {
std::vector<uint8_t> bytes;
for (size_t i = 0; input[i] && input[i + 1]; i += 2) {
std::string byte_string(input + i, 2);
bytes.push_back(static_cast<uint8_t>(std::stoi(byte_string, nullptr, 16)));
}
return bytes;
}
int main() {
// use custom literal
auto data = "A1B2C3D4"_B;
// print converted data
for (auto byte : data) {
std::cout << std::hex << static_cast<int>(byte) << ' ';
}
}When you run this code, you will see the following output:
a1 b2 c3 d4Read also:
- Sharing variable between bash scripts
- A 40-line LLM-based bash command executor in Python
- GTest and short-circuit evaluation in C++
- AI is powerful. Snippets are instant.
- From AUTOSAR to S-Core: the first C++ pub/sub implementation
- How to write Arduino Uno code with Python?
- Combining Bazel with Docker
- Running commands with timeout on Linux
- Running Python unit tests with CMake
- Thirdparty dependencies with FetchContent
- Bug of the week #11
- Combining CMake with Docker
- How to search the internet from Linux terminal?
- Folding expressions in C++
- How to derive from an enum in Python?
- Bug of the week #10
- Trying ROS2: client/server within a single container
- Make C++ a better place #4: Go as an alternative
- How to convert hex to dec in Linux terminal?
- Setting up a Python project with CMake
- Separating builds for different configs with Bazel
- Trying ROS2: pub/sub within a single container
- Bug of the week #9
- UDP multicasting with Python
- Destruction order vs thread safety in C++
- Let’s review some code: C++ #2
- Make C++ a better place #3: D as an alternative
- Registering callback using std::function in C++
- Bug of the week #8
- TCP client/server with Python
- Simple menus in Bash scripts with select
- Calling member function on a nullptr in C++
- Bug of the week #7
- Python lru_cache explained
- How to dockerize a Python application?
- Make C++ a better place #2: CppFront as an alternative
- Parameters combinations in GoogleTest
- Data transfer with curl
- Python reduce explained
- Bug of the week #6
- Custom literals in C++
- Linux and hash command
- 5 Python good practices which make life easier
- Let’s review some code: Python #1
- Make C++ a better place #1: What does better mean
- Enums vs enum class in C++
- Bug of the week #5
- UDP client/server with Python
- Hard links in Linux
- Functions calling order in unit tests in C++
- Bug of the week #4
- Yield in Python – state machines, coroutines and more
- Copy files from another branch with Git
- Make C++ a better place #0: Introduction
- 5 misconceptions about std::move in C++
- How to use xargs on Linux?
- How to test method call order with unittest in Python?
- Bug of the week #3
- Build & run C++ unit tests with CMake
- Arrange text with sort on Linux









