Search code examples
c++wxwidgets

C++ struct in a class with error: expected an identifier


Here is the simplest I think I can get this code:

class MyFrame : public wxFrame
{
public:
    MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size);

private:
    struct controlChoice
    {
        wxChoice *choice;
        int prevChoice;
    };
    wxPanel *panel;
    controlChoice *profileChoice;

}

MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
    : wxFrame(NULL, wxID_ANY, title, pos, size)
{
    this->panel = new wxPanel(this, wxID_ANY);
    controlChoice this->profileChoice;
    this->profileChoice->choice = new wxChoice(this->panel, wxID_ANY);
}

On the line "controlChoice this->profileChoice;" I receive "error: expected an identifier" and it's the "this" that's showing the error.

EDIT: removed the "does compile". Possibly it wasn't removing the previously successfully compiled executable and I just kept loading that.


Solution

  • The code does compile.

    That is not valid C++ syntax and any conformant C++ compiler should reject it as controlChoice is a typename while this->profileChoice is a qualified name and C++ grammar rules doesn't allow such an usage.


    You can instead use the member initializer list for initialization of those members:

    class MyFrame : public wxFrame
    {
    public:
        MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size);
    
    private:
        struct controlChoice
        {
            wxChoice *choice;
            int prevChoice;
            //add a constructor
            controlChoice(wxChoice *pChoice, int pPrevChoice): choice(pChoice), 
                                                               prevChoice(pPrevChoice)
        {
        }
        };
        wxPanel *panel;
        controlChoice *profileChoice;
    
    }
    MyFrame::MyFrame(const wxString &title, const wxPoint &pos, const wxSize &size)
        : wxFrame(NULL, wxID_ANY, title, pos, size), 
          panel(new wxPanel(this, wxID_ANY)),
          profileChoice(new controlChoice(new wxChoice(this->panel, wxID_ANY), 5))
    {
        
        //empty body as we did the initialization in the member initializer list
        
    }
    

    Note that initialization can be done in the member initializaer as opposed to assignment which is done in the constructor body. And since in the modified program we've used the member initializer list, we don't need to do anything else in the constructor body.