'Why cannot I use [] operator on std::shared_ptr<unsigned char[]>?

I'm writing an application for Arduino (more precisely, Teensy). While compiling the following code (last pasted line):

void executeActions(std::shared_ptr<unsigned char[]> actionData, const unsigned short actionBytes)
{
  unsigned short modifier = 0;
  Keyboard.set_modifier(modifier);

  int i = 0;
  while (i < actionBytes)
  {
    unsigned char action = actionData[i];

I'm getting the following error:

no match for 'operator[]' (operand types are 'std::shared_ptr<unsigned char []>' and 'int')

For reference, mentioned actionData is initialized in the following way (then passed a couple of times):

this->actionData = std::make_shared<unsigned char[]>(new unsigned char[this->actionBytes]);

What am I doing wrong?



Solution 1:[1]

In C++17 and later, std::shared_ptr has an operator[] (only when T is an array type). This operator does not exist in C++11..14, which is apparently what you are compiling for, or at a cursory glance, Arduino does not fully support C++17.

Also:

std::make_shared<unsigned char[]>(new unsigned char[this->actionBytes])

should be:

std::make_shared<unsigned char[]>(actionBytes)

But that is only available in C++20 and later.

In this situation, I would suggest using std::vector<unsigned char> instead of unsigned char[] (you should not be using new manually anyway), eg:

actionData = std::make_shared<std::vector<unsigned char>>(actionBytes);
void executeActions(std::shared_ptr<std::vector<unsigned char>> actionData)
{
  unsigned short modifier = 0;
  Keyboard.set_modifier(modifier);

  for(size_t i = 0; i < actionData->size(); ++i)
  {
    unsigned char action = (*actionData)[i];
    ...
  }

  /* simpler:
  for (auto action : *actionData)
  {
    ...
  }
  */

  ...
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1