3

I need to declare a class member array of structs that is ideally initialized at declaration like this:

class Foo
{
    typedef struct _TMember
    {
        uint16 m_key;
        uint16 m_val;
    }
    TMember;

    TMember m_member_tab[] =
    {
        { 10,    2400},
        { 20,    2500},
        { 30,    2600},
        { 40,    2700},
        { 50,    2650},
    };

    // etc...
};

Can this be done in traditional C++ (pre C++11) class header?

Edit: If not, what would be a good alternative? It'd be good to have the array as a class member, but otherwise it can be defined in a common header file.

artm
  • 17,291
  • 6
  • 38
  • 54
  • 1
    You have to keep in mind the [naming rules](http://stackoverflow.com/questions/228783/what-are-the-rules-about-using-an-underscore-in-a-c-identifier) and the One Definition Rule, but it otherwise works as shown. – chris Jul 13 '15 at 01:36
  • I got this error when using these declation in a C++ header : error: a brace-enclosed initializer is not allowed here before '{' token – artm Jul 13 '15 at 01:40
  • 2
    This is only allowed since C++11. – paddy Jul 13 '15 at 01:40
  • You can write `static const TMember m_member_tab[5];` in the header, and in one .cpp file, have the table – M.M Jul 13 '15 at 02:20
  • That means we need to know the number of element first? Could it be done with something like `sizeof( m_member_tab ) / sizeof( TMember )` (given the array has many items)? – artm Jul 13 '15 at 02:28
  • @artm No, you don't know what the size of the array is if you have not yet given it a size – M.M Jul 13 '15 at 02:35

1 Answers1

5

Static class variables used to have to be initialized in the implementation file, outside of the header.

With C++11, in-class initialization works if the static class variables is constexpr:

#include <iostream>

class Foo{
  public:
  struct TMember //can't start with an underscore; typedef unecessary in C++
  {
    unsigned short m_key;
    unsigned short m_val;
  };
  constexpr static TMember m_member_tab[]={
    { 10,    2400},
    { 20,    2500},
    { 30,    2600},
    { 40,    2700},
    { 50,    2650},
  };
};
int main()
{
  using namespace std;
  cout<<Foo::m_member_tab[1].m_val<<endl;
}

Old C++:

#include <iostream>

class Foo{
  public:
  struct TMember //can't start with underscore; typedef unecessary in C++
  {
    unsigned short m_key;
    unsigned short m_val;
  };
  static TMember m_member_tab[5];
};
//End of header, start of implementation 

Foo::TMember Foo::m_member_tab[] = {
    { 10,    2400},
    { 20,    2500},
    { 30,    2600},
    { 40,    2700},
    { 50,    2650},
  };
int main()
{
  using namespace std;
  cout<<Foo::m_member_tab[1].m_val<<endl;
}
Uours
  • 2,517
  • 1
  • 16
  • 21
Petr Skocik
  • 58,047
  • 6
  • 95
  • 142
  • Thanks. But as I mentioned in the Q, can it be done with traditional C++ (ie pre C++11). And if it's not, is there a good alternative? – artm Jul 13 '15 at 02:11
  • 1
    Added the C++98 version. – Petr Skocik Jul 13 '15 at 02:31
  • You can't have complex data structures in the C++98 header files, but you can define integer constants and/or enums in a C++98 class declaration so maybe you can somehow emulate your table with those... Otherwise, the static data has to go outside the header or you'll need to update your compiler. – Petr Skocik Jul 13 '15 at 02:37
  • 1
    do we really need to specify the array size (5) when we declare it? (c++98 version)? – artm Jul 13 '15 at 05:01
  • 1
    Your C++98 version works ok thanks. I just removed the array size (5) from declaration which is unnecessary. – artm Jul 13 '15 at 05:25