aarg:
I am curious. I am a huge fan of STL, or I was when I was coding for PC, that was some time ago. Are you telling me I can use such features safely and without much memory overhead in this MPU environment?
When using the STL on microcontrollers, there are two main concerns: dynamic memory usage and exceptions.
The same precautions of heap fragmentation that you have to take when using Arduino Strings still apply to all parts of the STL that allocate memory (e.g. std::string, std::vector, etc.).
Most Arduino Cores (e.g. AVR, Teensy) disable exceptions altogether, so if you use std::array::at with an index that’s out of bounds, it won’t throw an exception, but it’ll either just read/write out of bounds (like ArduinoSTL), or it’ll stop your program (Arduino-Helpers prints the error to Serial if debugging is enabled, and enter a loop blinking the built-in LED).
I don’t know what the toolchain’s STL does on ARM boards.
Espressif boards have exceptions enabled, so you can throw and catch exceptions like you would in a desktop application. An uncaught exception will abort the program, print a stack trace to Serial, and reset the chip.
Luckily large parts of the STL don’t rely on dynamic memory usage or exceptions, and it’s perfectly fine to use things like the standard algorithms, math functions, type traits, limits, std::array, std::tuple, std::optional, std::variant, etc. Again, there are cases where an exception could be thrown (array, optional, variant) so it’s up to you to make sure that this doesn’t happen.
Even though it uses dynamic memory, std::vector can still be very useful, and you can use it without problems if you preallocate them etc. Smart pointers are very handy when you occasionally do need dynamic memory allocations.
Some parts of the STL are not optimized for MCUs of course, so depending on the implementation, std::bitset<8> might use more than one byte of storage.
Personally, I haven’t had any problems with memory usage, even on AVR.
Here’s a simple std::sort example with cars and lanes to get you started:
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]Arduino_Helpers[/color][/b][color=#434f54].[/color]h[color=#434f54]>[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]AH[/color][/b][color=#434f54]/[/color]STL[color=#434f54]/[/color]algorithm[color=#434f54]>[/color] [color=#434f54]// std::sort[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]AH[/color][/b][color=#434f54]/[/color]STL[color=#434f54]/[/color]tuple[color=#434f54]>[/color] [color=#434f54]// std::tie[/color]
[color=#5e6d03]#include[/color] [color=#434f54]<[/color][b][color=#d35400]AH[/color][/b][color=#434f54]/[/color]PrintStream[color=#434f54]/[/color]PrintStream[color=#434f54].[/color]hpp[color=#434f54]>[/color] [color=#434f54]// Serial << ... << endl;[/color]
[color=#00979c]struct[/color] Car {
[color=#434f54]/// The lane this car is in.[/color]
[color=#00979c]uint8_t[/color] lane;
[color=#434f54]/// How many laps the car has left[/color]
[color=#00979c]uint8_t[/color] lapsLeft;
[color=#434f54]/// The timestamp when the car entered its current lap[/color]
[color=#00979c]unsigned[/color] [color=#00979c]long[/color] lapTime;
[color=#434f54]/// Less than operator to compare the position of two cars for sorting[/color]
[color=#00979c]bool[/color] [color=#00979c]operator[/color][color=#434f54]<[/color](Car that) [color=#00979c]const[/color] {
[color=#434f54]// Lexographically compare the number of laps left and the lap start time[/color]
[color=#5e6d03]return[/color] std[color=#434f54]:[/color][color=#434f54]:[/color]tie([color=#5e6d03]this[/color][color=#434f54]-[/color][color=#434f54]>[/color]lapsLeft[color=#434f54],[/color] [color=#5e6d03]this[/color][color=#434f54]-[/color][color=#434f54]>[/color]lapTime)
[color=#434f54]<[/color] std[color=#434f54]:[/color][color=#434f54]:[/color]tie(that[color=#434f54].[/color]lapsLeft[color=#434f54],[/color] that[color=#434f54].[/color]lapTime);
[color=#434f54]// The number of laps left is the most important criterion, if a car has more[/color]
[color=#434f54]// laps left, it's always behind the other car.[/color]
[color=#434f54]// If they have the same number of laps left, the car that passed the[/color]
[color=#434f54]// checkpoint/counter first is (probably) before the other car.[/color]
}
};
Car cars[color=#000000][[/color][color=#000000]][/color] [color=#434f54]=[/color] {
{1[color=#434f54],[/color] 3[color=#434f54],[/color] 1000}[color=#434f54],[/color] [color=#434f54]// Car in lane 1, has 3 laps left, started this lap at t=1000ms[/color]
{2[color=#434f54],[/color] 2[color=#434f54],[/color] 1200}[color=#434f54],[/color]
{3[color=#434f54],[/color] 2[color=#434f54],[/color] 1100}[color=#434f54],[/color]
{4[color=#434f54],[/color] 2[color=#434f54],[/color] 1300}[color=#434f54],[/color]
};
[color=#00979c]void[/color] [color=#5e6d03]setup[/color]() {
[b][color=#d35400]Serial[/color][/b][color=#434f54].[/color][color=#d35400]begin[/color](115200);
[color=#5e6d03]while[/color] ([color=#434f54]![/color][b][color=#d35400]Serial[/color][/b]);
[color=#434f54]// Sort the array of cars by position[/color]
std[color=#434f54]:[/color][color=#434f54]:[/color]sort(std[color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]begin[/color](cars)[color=#434f54],[/color] std[color=#434f54]:[/color][color=#434f54]:[/color][color=#d35400]end[/color](cars));
[color=#434f54]// Print the leader board to Serial[/color]
[color=#5e6d03]for[/color] ([color=#00979c]const[/color] Car [color=#434f54]&[/color]car [color=#434f54]:[/color] cars)
[b][color=#d35400]Serial[/color][/b] [color=#434f54]<<[/color] car[color=#434f54].[/color]lane [color=#434f54]<<[/color] endl;
[color=#434f54]// Expected output:
// 3
// 2
// 4
// 1
// Implementation tips:
//
// 1. Initialize all cars with their lane number, set the laps remaining
// to the total number of laps, e.g. 5, initialize the lap start time to
// zero.
// 2. When a car passes the checkpoint/counter, subtract one from the laps
// remaining, and record the current time as the lap start time.
// 3. Sort the array of cars as shown above, and print the leaderboard.
//
// There are two options too look up a car given its lane:
//
// a. Keep the main cars array sorted by lane number, so you can get the
// array index from the lane number directly.
// When sorting the array, don't sort the main cars array, but sort a copy
// of the array.
// b. Sort the main cars array by position, and look up the car by lane
// number using std::find.[/color]
}
[color=#00979c]void[/color] [color=#5e6d03]loop[/color]() {}