Template value class inheriting name from base

For an example code I just want a template class that can take any value (say int) that inherits a char array (name) from the base class so that it can be initialized with it

template<class T> 
  class valueitem: public nameitem{
  

		  public:
		  T value;
		  
		    valueitem(char* myname="",T Value):menuitem(char* myname){
			value=Value;
				
			}
		
	  };

class  nameitem
{
public:
char name[10];

nameitem(char* myname){
strcpy(name, myname);
}
};

valueitem<int> Temperature("roomtemp: "); //These are the initialization parameters I want
Temperature.value=24;
Serial.print(roomtemp.name);
Serial.println(roomtemp.value);

The idea is that I want to be able to initialize e.g valueitem Temperature("roomtemp: ");

An integer valueitem class object called temperature with name roomtemp, so that I can e.g:

Serial.print(roomtemp.name);
Serial.println(roomtemp.value);

and it will print roomtemp: 23

But I get expected class-name before ‘{’ token error.

this is not Python… you can’t get code in the middle of nowhere…and in Arduino world, you need a setup() and a loop().

does this help?

class NameItem
{
  public:
    static const uint8_t maxName = 20;
    char name[maxName + 1];
    NameItem(const char* myname) {
      strncpy(name, myname, maxName);
      name[maxName] = '\0'; // just in case we overflow
    }
};

template <class T> class ValueItem: public NameItem
{
  public:
    T value;
    ValueItem(const char* myname, T v): NameItem(myname), value(v) {}
};

void setup()
{
  Serial.begin(115200);

  ValueItem<float> temperature("roomtemp: ", 24.57);
  Serial.print(temperature.name);
  Serial.println(temperature.value);

  ValueItem<char> keyCode("key: ", 'z');
  Serial.print(keyCode.name);
  Serial.println(keyCode.value);

  ValueItem<uint32_t> microTimeNow ("Time: ", micros());
  Serial.print(microTimeNow.name);
  Serial.println(microTimeNow.value);
}

void loop() {}

You should see in the console set at 115200 bauds

[color=purple]roomtemp: 24.57
key: z
Time: 528
[/color]

and of course you can embed the printing in the subclass too and I added information to demonstrate that the right amount of storage has been allocated for value

class NameItem
{
  public:
    static const uint8_t maxName = 20;
    char name[maxName + 1];
    NameItem(const char* myname) {
      strncpy(name, myname, maxName);
      name[maxName] = '\0'; // just in case we overflow
    }
};

template <class T> class ValueItem: public NameItem
{
  public:
    T value;
    ValueItem(const char* myname, T v): NameItem(myname), value(v) {}
    void printOut()
    {
      Serial.print(name);
      Serial.print(value);
      Serial.print("\t--> value has ");
      Serial.print(sizeof(value));
      Serial.println(" bytes");
    }
};

void setup()
{
  Serial.begin(115200);

  ValueItem<float> temperature("roomtemp: ", 24.57);
  temperature.printOut();

  ValueItem<char> keyCode("key: ", 'z');
  keyCode.printOut();

  ValueItem<uint32_t> microTimeNow ("Time: ", micros());
  microTimeNow.printOut();
}

void loop() {}

You should see in the console set at 115200 bauds

[color=purple]roomtemp: 24.57	--> value has 4 bytes
key: z	--> value has 1 bytes
Time: 1004	--> value has 4 bytes[/color]

Thank you for providing something that compiles but what do you mean by “can’t get code in the middle of nowhere…” ? If you were referring to the setup() and loop() I did have them in the arduino IDE but I was only trying to understand why my class wouldn’t compile by itself even in notepad++.

I needed to swap the order of your NameItem and ValueItem definitions since ValueItem derives from NameItem and because order matters in local scope? And I cant have only one default argument in my ValueItem’s constructor parameter list.

I meant that in the code you posted initially there was the class and then some lines of wide out of any functions - if that was just to explain what you were doing that’s OK.

ValueItem depends on NameItem => So you need to declare NameItem before ValueItem.

what do you mean by:

And I cant have only one default argument in my ValueItem's constructor parameter list

In C++, base class constructors are automatically called for you if they have no argument.

If you want to call a superclass constructor with an argument, you must use the subclass's constructor initialization list. As C++ supports multiple inheritance, the base class must be referred to by name, as what you have in other languages to refer to the parent classs (“super”) could be ambiguous.

class MySuperClass {
    public:
        MySuperClass(int a) { /* do something with a */}
};
class MySubClass : public MySuperClass {
    public:
        MySubClass(int a, int b) : MySuperClass(a)    // Call the superclass constructor as part of initialization list. This is called "constructor chaining"
        { /* do something with b */}
};

of course you are not obliged to use the constructor chaining syntax and the parent class's constructor can be called explicitly from the derived member's constructor function.

I cant have only one default argument in my ValueItem’s constructor parameter list. Yes thanks for clearing up the Constructor Chaining, I wasn’t sure why mine wasn’t working, see below.

valueitem(char* myname="",T Value):menuitem(char* myname){
value=Value;
}

should be:

valueitem(char* myname="",T Value=0):menuitem(char* myname){
value=Value;
}

So just to fix what I had earlier:

class  MenuItem
{
  public:
  char name[16];
  menuitem(char *myname)
  {
    strcpy(name, myname);
  }
  
void (*entryfunction) ();
void (*exitfunction) ();
};

template<class T> class ValueItem: public MenuItem
{
  

 public:
  T value;
  ValueItem(char* myname="",T Value=0):MenuItem(myname),value(Value){}
    
};

I changed NameItem to MenuItem, since I am introducing a new class Menu.

class menu:menuitem
{
public:
  menu(const char *myname, byte y, byte x, byte m_color);
  ~menu();
menuitem*** menulist;
menu* previous_menu; //pointer to previous menu
};

menu::menu(const char *myname="", byte y=0, byte x=0)
{
    strcpy(name, myname);
    menulist=0;


    if (y>0)
    {
      menulist = new menu**[y+1];
      menulist[y]=0;
      for (byte i=0; i<=y; i++)
      { 
        menulist[i] = new menu*[x+1];
        for (byte p=0; p<=x; p++)
          menulist[i][p]=0;
      }
      
    }
};


  menu::~menu(){
    for(int i = 0; menulist[i]!=0; ++i) {
      delete [] menulist[i];
    }
    delete [] menulist;

  }

I want Menu to be derived from MenuItem, and to act as a container for itself and other objects derived from MenuItem. It is a 2D MenuItem pointer array.

Then lets say I want to create a menu for changing the time and date:

Menu SET_TIME("Time/Date",2,4,0);
ValueItem<int> set_hour("Time:",0,0,0), set_minute(":"), set_second(":"), 
                        set_year("/"), set_month("/"), set_day("DATE:");

void setup(){
  SET_TIME.menulist[0][1]=&set_hour; //menulist[0][0] reserved for previous Menu
  SET_TIME.menulist[0][2]=&set_minute;
  SET_TIME.menulist[0][3]=&set_second;
  SET_TIME.menulist[1][0]=&set_day;
  SET_TIME.menulist[1][1]=&set_month;
  SET_TIME.menulist[1][2]=&set_year;
}
void loop(){
//update the time variables
}

All the above ValueItems are contained in Menu SET_TIME and if it iterates through the menulist array it has, it should print their name and Value so that the above looks like e.g:

Time: 12:00:00
Date: 12/12/2012

My question is how can I create the MenuItem array with MenuItem*** menulist; but still store ValueItems, MenuItems, and other Menus inside it and access their members?

I’ve read about “object slicing” where ‘“Slicing” is where you assign an object of a derived class to an instance of a base class, thereby losing part of the information - some of it is “sliced” away.’

But I’m not sure that is what I need to use or not.

What do you use when you want to have a mixed array but from the same hierarchy? If you’re writing a game with a base class for which the player and various enemies are derived and you need a base class list of all the players and enemies to iterate through to draw sprites etc what do you use?

syphex:
What do you use when you want to have a mixed array but from the same hierarchy? If you're writing a game with a base class for which the player and various enemies are derived and you need a base class list of all the players and enemies to iterate through to draw sprites etc what do you use?

Your code and your description are pretty unclear, but perhaps it's a job for Polymorphism? An array of type base class can have pointers to any number of objects of derived classes. The base class provides the interface definitions and the derived classes implement them in a manner specific to each one.

EDIT:
Please start again by posting all your latest proposed code in one set of Code Tags rather than distributed across several. Include setup() and loop() so we can actually copy into the IDE and compile. Also, include instantiations of the objects as many compile errors don't show up until you try to make an object each class.

I’m getting a bit lost between you explanation of what’s working and you were doing wrong (which I know of :grin: ) and your questions… :smiley:

in order to play around with concepts, I would suggest you put aside your specific use case and create dummy classes as I did. Once the hierarchy and initialization path is working the way you want, then you can add your specifics

As @gfvalvo explains, you could gather all your instances in an array of type of the base class. A ValueItem is a kind of MenuItem with more information.

J-M-L:
I'm getting a bit lost between you explanation of what's working and you were doing wrong (which I know of :grin: ) and your questions... :smiley:

Sorry about that! Your first answer perfectly solved the first part of my problem. I've now introduced a new problem by adding another derived class that I want to use as a container for the previous classes.

I tried my best to clean it up a bit and try to describe what functionality I am trying to achieve afterwards. I am having difficulty writing code which even compiles as you can see.. so creating dummy classes is difficult. I tried to have a go at instantiating an example of what I am trying to do with the time menu.

As I said, "I want Menu to be derived from MenuItem, and its objects to act as a container for objects of type Menu and other objects belonging to classes derived from MenuItem. A Menu object contains a 2D MenuItem pointer array."

gfvalvo:
Your code and your description are pretty unclear, but perhaps it's a job for Polymorphism? An array of type base class can have pointers to any number of objects of derived classes. The base class provides the interface definitions and the derived classes implement them in a manner specific to each one.

Yes this is what I need, but since Menu derives from MenuItem we are already using Polymorphism no? So now everything must be handled via virtual functions inside the base class (in this case MenuItem) and implemented in its derived classes, I understand that.

I think its an aggregate. A Menu object can "have" a ValueItem, MenuItem, or even another Menu object by means of the menulist array.

If what you say is true, that I can just create a MenuItem array inside a Menu object; Then what I wrote should be correct and make sense.. otherwise I have no idea what I'm doing.

J-M-L:
As @gfvalvo explains, you could gather all your instances in an array of type of the base class. A ValueItem is a kind of MenuItem with more information.

Slight correction because what I originally wrote was incorrect - You gather everything into an array of type pointer to base class. Even though each element of the array is of that type, it actually points to an object of derived class. Each derived class implements (in a custom way) the virtual functions declared in base class.

gfvalvo:
Slight correction because what I originally wrote was incorrect - You gather everything into an array of type pointer to base class. Even though each element of the array is of that type, it actually points to an object of derived class. Each derived class implements (in a custom way) the virtual functions declared in base class.

Could you please provide an example? Do I just treat the base class pointer array as if it were a pointer array of one of the derived types? Otherwise how do I access it?

Here is a tidied up version of what I was trying to put together above minus actually iterating through a menulist array.

class  MenuItem //just holds a name i.e char string
{
  public:
  char name[16];
  MenuItem(char *myname)
  {
    strcpy(name, myname);
  }
  
void (*entryfunction) ();
void (*exitfunction) ();
};

template<class T> class ValueItem: public MenuItem //inherits name from base and holds any value type
{
  

 public:
  T value;
  ValueItem(char* myname="",T Value=0):MenuItem(myname),value(Value){}
    
};

class Menu: public MenuItem //container object for other Menu objects or its derivations
{
public:
  Menu(const char *myname, byte y, byte x);
  ~Menu();
MenuItem*** menulist;
MenuItem* previous_menu; //pointer to previous menu
};

Menu::Menu(const char *myname="", byte y=0, byte x=0):MenuItem(name)
{
    strcpy(name, myname);
    menulist=0;


    if (y>0)
    {
      menulist = new MenuItem**[y+1];
      menulist[y]=0;
      for (byte i=0; i<=y; i++)
      { 
        menulist[i] = new MenuItem*[x+1];
        for (byte p=0; p<=x; p++)
          menulist[i][p]=0;
      }
      
    }
};

  Menu::~Menu(){
    for(int i = 0; menulist[i]!=0; ++i) {
      delete [] menulist[i];
    }
    delete [] menulist;

  }

Menu SET_TIME("Time/Date",2,4); //Type Menu to act as container for following ValueItem //objects

ValueItem<int> set_hour("Time:"), set_minute(":"), set_second(":"), 
                        set_year("/"), set_month("/"), set_day("DATE:");


void setup() {
Serial.begin(9800);
  
  SET_TIME.menulist[0][1]=&set_hour; //menulist[0][0] reserved for previous Menu
  SET_TIME.menulist[0][2]=&set_minute;
  SET_TIME.menulist[0][3]=&set_second;
  SET_TIME.menulist[1][0]=&set_day;
  SET_TIME.menulist[1][1]=&set_month;
  SET_TIME.menulist[1][2]=&set_year;

Serial.println(SET_TIME.menulist[0][1]->name);
}

void loop() {
  // put your main code here, to run repeatedly:

}

Should print "Time: "

In this case if I wanted to access a member of the array could I use e.g Serial.println(SET_TIME.menulist[0][1]->name);
to print set_hour’s name (which is "Time: ") ? In that case I believe it works and I am done.

This compiles, but I don’t have an arduino on me at the moment…

I think you are over engineering your Object Oriented approach there.

A menu is something that can hold an ordered list of either menu or leaves. leaves can have a call back function attached for example. (but so do intermediary menu items, you could want to trigger something as you dive in)

that would be something like

class Menu
{
  public:
    static const uint8_t maxName = 20;
    Menu(const char* myname, void (*callBack)(void) = NULL) : action(callBack)
    {
      strncpy(label, myname, maxName);
      label[maxName] = '\0'; // just in case we overflow
      subMenu = NULL;
      nbEntries = 0;
    }

    char label[maxName + 1];
    uint8_t nbEntries;
    Menu** subMenu;
    void (*action)(void);
};

void f1(void) {
  Serial.println("f1");
}
void f2(void) {
  Serial.println("f2");
}
void f3(void) {
  Serial.println("f3");
}
void f4(void) {
  Serial.println("f4");
}
void f5(void) {
  Serial.println("f5");
}

// we build up the Menu hierarchy starting from the leaves

Menu f1Menu("f1", f1);
Menu f2Menu("f2", f2);
Menu f3Menu("f3", f3);
Menu f4Menu("f4", f4);
Menu f5Menu("f5", f5);

Menu* M1[] = {&f1Menu, &f2Menu};
Menu* M2[] = {&f3Menu, &f4Menu, &f5Menu};

Menu subM1("M1");
Menu subM2("M2");

Menu* M0[] = {&subM1, &subM2};

Menu topMenu("Top Menu");

void displayMenuTree(Menu* m, uint8_t indent = 0)
{
  Serial.println(m->label);
  for (uint8_t i = 0; i < m->nbEntries; i++) {
    for (uint8_t p = 0; p < indent+1; p++) Serial.print("  ");
    if (m->subMenu[i] != NULL) displayMenuTree(m->subMenu[i], indent + 1);
  }
}

void setup()
{
  Serial.begin(115200);

  // organize the Menu
  topMenu.subMenu = M0;
  topMenu.nbEntries = sizeof(M0) / sizeof(M0[0]);

  subM1.subMenu = M1;
  subM1.nbEntries = sizeof(M1) / sizeof(M1[0]);

  subM2.subMenu = M2;
  subM2.nbEntries = sizeof(M2) / sizeof(M2[0]);

  displayMenuTree(&topMenu);
}

void loop() {}

Running this basically builds up the menu trees and calls displayMenuTree(). You should see this in the console

[color=purple]
Top Menu
  M1
    f1
    f2
  M2
    f3
    f4
    f5
[/color]

J-M-L:
I think you are over engineering your Object Oriented approach there.

A menu is something that can hold an ordered list of either menu or leaves. leaves can have a call back function attached for example. (but so do intermediary menu items, you could want to trigger something as you dive in)

that would be something like

class Menu

{
  public:
    static const uint8_t maxName = 20;
    Menu(const char* myname, void (*callBack)(void) = NULL) : action(callBack)
    {
      strncpy(label, myname, maxName);
      label[maxName] = ‘\0’; // just in case we overflow
      subMenu = NULL;
      nbEntries = 0;
    }

char label[maxName + 1];
    uint8_t nbEntries;
    Menu** subMenu;
    void (*action)(void);
};

void f1(void) {
  Serial.println(“f1”);
}
void f2(void) {
  Serial.println(“f2”);
}
void f3(void) {
  Serial.println(“f3”);
}
void f4(void) {
  Serial.println(“f4”);
}
void f5(void) {
  Serial.println(“f5”);
}

// we build up the Menu hierarchy starting from the leaves

Menu f1Menu(“f1”, f1);
Menu f2Menu(“f2”, f2);
Menu f3Menu(“f3”, f3);
Menu f4Menu(“f4”, f4);
Menu f5Menu(“f5”, f5);

Menu* M1 = {&f1Menu, &f2Menu};
Menu* M2 = {&f3Menu, &f4Menu, &f5Menu};

Menu subM1(“M1”);
Menu subM2(“M2”);

Menu* M0 = {&subM1, &subM2};

Menu topMenu(“Top Menu”);

void displayMenuTree(Menu* m, uint8_t indent = 0)
{
  Serial.println(m->label);
  for (uint8_t i = 0; i < m->nbEntries; i++) {
    for (uint8_t p = 0; p < indent+1; p++) Serial.print("  ");
    if (m->subMenu[i] != NULL) displayMenuTree(m->subMenu[i], indent + 1);
  }
}

void setup()
{
  Serial.begin(115200);

// organize the Menu
  topMenu.subMenu = M0;
  topMenu.nbEntries = sizeof(M0) / sizeof(M0[0]);

subM1.subMenu = M1;
  subM1.nbEntries = sizeof(M1) / sizeof(M1[0]);

subM2.subMenu = M2;
  subM2.nbEntries = sizeof(M2) / sizeof(M2[0]);

displayMenuTree(&topMenu);
}

void loop() {}




Running this basically builds up the menu trees and calls displayMenuTree(). You should see this in the console




Top Menu
  M1
    f1
    f2
  M2
    f3
    f4
    f5

Ah yes that does seem simpler. That’s basically what I was going for except I wanted the list of members to be 2D so its easier to organise which members belong on which line/col on an LCD screen.

For example you might want:

Top Menu
M1
F1
F2
M2
F3 F4 F5

Could you replace

Menu* M2[] = {&f3Menu, &f4Menu, &f5Menu};

with

Menu** M2[] = Menu* M2[] = {{&f3Menu}, {&f4Menu}, {&f5Menu}};

And tweak displayMenuTree to get the desired effect above?

If you also wanted to add values of any type which also have names to your list how would you implement it without “over engineering” it?

How can I change my code so that I can use:

SET_TIME.menulist = {{&set_hour, &set_minute, &set_second},{&set_year, &set_month, &set_day}};

Instead of :

SET_TIME.menulist[0][1]=&set_hour; //menulist[0][0] reserved for previous Menu
  SET_TIME.menulist[0][2]=&set_minute;
  SET_TIME.menulist[0][3]=&set_second;
  SET_TIME.menulist[1][0]=&set_day;
  SET_TIME.menulist[1][1]=&set_month;
  SET_TIME.menulist[1][2]=&set_year;

I would keep the menus "flat" and add instance variables describing how you want to lay-out the menu (nb of rows, number of column for example).

You could add NULL entries in the list if you don't have a perfect matrix

Isn't there a way it could just count the number of rows and columns based on the 2d array list that I give it and then back fill it with 0's? It really would make the assignment of menu's much nicer if I could do it as above.

the class has only the notion of a pointer to pointer of Menu. it does not know how many rows or lines you have, this information is not kept in the array definition. it's for you to know. that's why you can't even know how many elements you have in the array and in the setup I have   topMenu.nbEntries = sizeof(M0) / sizeof(M0[0]);

a good design pattern would be to separate the presentation layer from the abstraction. So store the data as a flat list and then either within the class or as a separate class, attach information about the layout.

J-M-L:
the class has only the notion of a pointer to pointer of Menu. it does not know how many rows or lines you have, this information is not kept in the array definition. it's for you to know. that's why you can't even know how many elements you have in the array and in the setup I have   topMenu.nbEntries = sizeof(M0) / sizeof(M0[0]);

a good design pattern would be to separate the presentation layer from the abstraction. So store the data as a flat list and then either within the class or as a separate class, attach information about the layout.

I understand that but the layout is so straight forward it really doesn't seem worth implementing separately.

Menu*** menulist would be an array of an array of Menu pointers? Its a 2D array of Menu pointers so it should work.

The first layer tells you the number of lines, and the next layer is the number of columns.

int cols = sizeof(menulist) / sizeof(menulist[0]);
int rows = sizeof(menulist[0]) / sizeof(menulist[0][0]);

Or something.

I just don't understand why I can do:

SET_TIME.menulist[0][1]=&set_hour; //menulist[0][0] reserved for previous Menu
  SET_TIME.menulist[0][2]=&set_minute;
  SET_TIME.menulist[0][3]=&set_second;
  SET_TIME.menulist[1][0]=&set_day;
  SET_TIME.menulist[1][1]=&set_month;
  SET_TIME.menulist[1][2]=&set_year;

But cant do

SET_TIME.menulist = {{&set_hour, &set_minute, &set_second},{&set_year, &set_month, &set_day}};

the notion of 1D or 2D or 3D arrays is just an abstraction. In reality the compiler does not store the dimensions anywhere, you just have consecutively in memory some data

for examplebyte myArray[2][3] {{1,2,3}, {4,5,6}}; will just result in storing consecutively in memory | 1 | 2 | 3 | 4 | 5 | 6 |

As long as you access the data using the variable name myArray, the compilers knows the dimensions and will do the right thing

but if you do byte* arrayPtr = (byte*) myArray; then the dimensions are lost as the compiler does not know how many elements are pointed. it’s for you to know.

for example If I use that code

byte myArray[2][3] = {{1, 2, 3}, {4, 5, 6}};

byte* arrayPtr = (byte*) &myArray;

void setup()
{
  Serial.begin(115200);

  Serial.println("--- SIMPLE 3x2 ARRAY DUMP ---");
  for (byte r = 0; r < 2; r++) {
    for (byte c = 0; c < 3; c++) {
      Serial.print(myArray[r][c]);
      Serial.print(" ");
    }
    Serial.println();
  }
  Serial.println();
  Serial.println("--- MEMORY DUMP 6x1 ---");

  for (byte i = 0; i < 6; i++) { // I know I've 6 elements
    Serial.print(*(arrayPtr+i)); // just printing the data in consecutive memory slots
    Serial.print(" ");
  }
  Serial.println();
  Serial.println();
  
  Serial.println("--- MEMORY DUMP ORGANIZED THE WAY I WANT 2x3 ---");
  for (byte r = 0; r < 3; r++) {
    for (byte c = 0; c < 2; c++) {
      Serial.print(*(arrayPtr + 2*r+c));
      Serial.print(" ");
    }
    Serial.println();
  }
}

void loop() {}

the console will show

[color=purple]
--- SIMPLE 3x2 ARRAY DUMP ---
1 2 3 
4 5 6 

--- MEMORY DUMP 6x1 ---
1 2 3 4 5 6 

--- MEMORY DUMP ORGANIZED THE WAY I WANT 2x3 ---
1 2 
3 4 
5 6 

[/color]

first print is by iterating through rows and columns.
but if I keep only a pointer to the start of the memory, you can see that by just going through the memory consecutively I can find and print my 6 values in a line. (6x1)
in the last example, I present the same data in 3 lines of 2 columns

→ so it’s just a matter of deciding how you want to show the information

==> as your menu can hold a variable number of entries (and once you allocate the array to the instance variable in your class you lose the info and you only keep a pointer to the start), unless you store somewhere the dimension of the array or the layout you want, you’ll be stuck

I have decided on the following approach, thank you for your contribution to my understanding of arrays, please now help me with the topic at hand. I am trying to print the names and values to an LCD screen. Below is my code just trying to print 2 lines manually for debugging purposes. As you can see I am trying to print the value inside a ValueItem object which is being pointed to by a MenuItem* array. Since the base class doesn’t know about Value, I am trying dynamic_cast. But I am getting a ‘dynamic_cast’ not permitted with -fno-rtti error, even though MenuItem is PolyMorphic.

#include <Wire.h>
#include <Adafruit_MCP23017.h>
#include <Adafruit_RGBLCDShield.h>

class  MenuItem
{
public:
char Name[15];
//void* value;

virtual GetValue(){}

MenuItem(char* MyName){
strcpy(Name, MyName);
}
};

template <byte x, byte y>class Menu:MenuItem
{
  public:
  MenuItem* MenuList[x][y]={{0}}; 
  Menu(const char* MyName):MenuItem(Name){
    strcpy(Name, MyName);
   
  }
};

template <class T> class ValueItem: public MenuItem
{
    public:
    T value;
    const char* UnitStr;
    ValueItem(const char* MyName="",const char* Unit="", T Value=0): MenuItem(MyName)
    {
      value=Value;
      UnitStr=Unit;    
    }

     GetValue() // Cant use T GetValue() :(
    {
      return (T)value;
    }
};

  Menu<1,2> Main("Main: ");
  MenuItem Label_Temperature("Air Temp"); 
  ValueItem<float> Temperature("Temp: ","\xDF\C",24.6);

// The shield uses the I2C SCL and SDA pins.
Adafruit_RGBLCDShield lcd = Adafruit_RGBLCDShield();



void setup() {
  // Debugging output
  Serial.begin(9600);
  // put your setup code here, to run once:

   Main.MenuList[0][0]=&Label_Temperature;
   Main.MenuList[0][1]=&Temperature;
   Serial.println(Label_Temperature.Name);
   Serial.print(Temperature.Name);
   Serial.print(Temperature.value);
   Serial.print(Temperature.UnitStr);

  lcd.begin(16, 2);

  lcd.print("Hello, world!");
  delay(1000);
  lcd.clear();
  lcd.print(Main.MenuList[0][0]->Name);
  lcd.setCursor(0, 1);
  lcd.print(Main.MenuList[0][1]->Name);
  //lcd.print(Temperature.value);              //works
  lcd.print((dynamic_cast<ValueItem<float>*>(Main.MenuList[0][1]))->GetValue()); //does not work
  lcd.print(Temperature.UnitStr);
}

uint8_t i=0;
void loop() {
}

The problem is that if I try to GetValue() without dynamic cast it is treated as an integer. Also GetValue() has no return type, because if I try T GetValue() then I get “conflicting return type specified for ‘T ValueItem::GetValue() [with T = float]’” error, which makes no sense to me as the return type is clearly specified as type T in that case?

I have decided on the following approach

walk me through your thoughts. By templating how many subMenus your menu holds (x and y) you will create as many types as you have layout and you won't be able to easily write functions traversing the Menus as they will all be of different unknown types.

In my view, the number of elements in the menu does not warrant a specific class, it's just instance variables of your Menu class.

Yes you are right It wasn't my intention to create so many types for each different layout. Previously as you can see I dynamically allocated arrays using x and y instead of using templates. But the size of the lists doesn't change at runtime so I thought it would be better to avoid dynamic pointer arrays because of memory leaks etc. I was mistaken as I will have too many types and duplicated code. I will change it to a 1D array and keep track of x and y and arrange the list as per your approach, I just needed a reason to do it that way but now it makes sense.

But please now help me to solve the problem at hand between the derived classes ValueItem and Menu and the base class MenuItem

My reasoning was that an item in the menu (hence the MenuItem Base class) would contain either a linked list of other MenuItems, or be responsible for tracking and changing a value, which can be of any type, but both require a name. So it seemed like Polymorphism would be the best approach, especially since I might be adding functions pertinent to those separate classes (like getting the value, changing it, vs navigating a list of other objects). That is the definition of Polymorphism (many types).

Since it seems like a waste for a MenuItem to have a list allocated to it (even if its empty), when it's just storing a value or vica versa; being forced to template a Value member variable it won't use when its only intention is to store a list (like MenuItem Main); it seemed better to have separate classes to store the respective information.

Please refer to https://www.learncpp.com/cpp-tutorial/12-9-dynamic-casting/ . Since I have in effect a pointer to a base class but want to access derived information, as per the link what I want to do is downcast from the base class to the respective derived class to access the derived information.

As long as each object keeps track of its own information (size and members of array or type of value etc) I can write functions for each class to retrieve that information, and there wont be any unnecessary information stored, or so I thought.