Search code examples
c++visual-studio-6

Was it possible to get a pointer to member from an instance of an object?


I was porting some legacy code to VS 2015 when this compiler error halted the build:

error C3867: 'OptDlg::GetFullModel': non-standard syntax; use '&' to create a pointer to member

Going to the corresponding file and line, I saw this:

Manager mgr = GetDocument()->GetManager();
OptDlg dlg;
...
mgr->SetFullModel(dlg.GetFullModel);
if ( dlg.GetFullModel )
    mgr->SetSymm(...

GetFullModeland SetFullModel are the getter/setter pair for a member variable in two different classes:

class Manager {
    ...
    bool GetFullModel() { return m_bFullModel; }
    void SetFullModel(bool bFlag) { m_bFullModel = bFlag; }
    ....
};

class OptDlg {
    ...
    void GetFullModel() { return m_bFullModel; }
    void SetFullModel(bool bValue) { m_bFullModel = bValue; if ( bValue ) m_bInside = 0;}

Yep, something's wrong. Was dlg.GetFullModel supposed to be a pointer to a member function? I thought those use the class name, not an instance. Not to mention what that would mean for execution semantics...

C++ is still relatively new to me, so I tried Google. It had a lot on function pointers, but they all looked different from what I had:

&OptDlg::GetFullModel // Standard-compliant

vs

OptDlg::GetFullModel // The "normal" way to mess up getting a pointer to member, it seems

vs

dlg.GetFullModel // ?

Is dlg.GetFullModel just another way of getting a pointer to member function? If not, what is the "standard C++ version", if there is one? Is this just another one of those VS 6 "extensions"?


Solution

  • &OptDlg::GetFullModel // Standard-compliant

    If your parameter types were supposed to be taking member functions, that's what you'd use. But they take booleans. It looks like you're just missing parentheses on your function calls, and it should be:

    mgr->SetFullModel(dlg.GetFullModel());
    if (dlg.GetFullModel())
        mgr->SetSymm(...
    

    Probably someone was ignoring warnings (or didn't have them on) and hence a pointer value (being produced through whatever shady means) was always being interpreted as non-NULL, hence boolean true.

    Is this just another one of those VS 6 "extensions"?

    It would appear to be the case, although this comment is the only documented evidence I can find it was an intentional/advertised "feature". Don't see any formal announcement of it being added or taken out.