0

In an effort to minimise memory consumption in microcontroller code, I decided to create a struct to hold constant strings, then re-use these across the application so the strings only need to be stored once in memory.

I now want to use these for the keys in an icon map (as seen below), but I get the following error invalid use of non-static data member 'sensor_type::apparent_power'.

What do I need to change to make this work? Is there a better structure to hold constant strings that I can statically access? I want to be able to access these globally without needing to create instances.

Could this be the solution or am I approaching the problem incorrectly?

struct sensor_type {
  static constexpr const char *apparent_power = "apparent_power";
}

My original code:

struct sensor_type {
  const char *apparent_power = "apparent_power";
}
// this works
if (tokens.at(1) == sensor_type::apparent_power) {
  // ...
}

// this does not work
const std::map<const char*, const char*> sensor_icon_map {
  {sensor_type::apparent_power, "\u0B17"}
}
oli_taz
  • 197
  • 1
  • 4
  • 18
  • 1
    Please note that when you use a pointer as the key for a map, it's the *pointer* that's the key, not the string (or other object) it might point to. In your case, if you have two different pointers, for example one is the `apparent_power` variable, and another is an array stored somewhere else, then they won't match, even if `strcmp` would consider the strings equal. If you need to use strings as keys, use `std::string` instead. Or possibly the Arduino `String` class. – Some programmer dude Aug 29 '23 at 10:05
  • Consider using frozen for a constant map - https://github.com/serge-sans-paille/frozen – Den-Jason Aug 29 '23 at 10:06
  • `static constexpr` is a solution. – Jarod42 Aug 29 '23 at 10:13
  • 1
    If you want compare pointers, you map is ok, if it is the string, then key should be `std::string_view` (with no ownership) or `std::string` (with ownership). – Jarod42 Aug 29 '23 at 10:15
  • *"// this works"* / *"// this does not work"*. Both are similar though. I suppose you are in different scope, one inside the class (so equivalent to `this->apparent_power`), one outside the class. – Jarod42 Aug 29 '23 at 10:18
  • Thanks for the comments, as it has been suggested, the first thing I will do is change to using `std::string`. Reading [this SO question](https://stackoverflow.com/questions/4157687/using-char-as-a-key-in-stdmap) also highlighted the issue. I was trying to reduce the overhead but it's not worth it. – oli_taz Aug 29 '23 at 16:39
  • Unfortunately `std::string_view` isn't available in Arduino and the use of third-party libraries is discouraged in the platform I am creating a plugin for, so `std::string` is the only viable option right now. Thanks for the help! – oli_taz Aug 29 '23 at 18:38

0 Answers0