3

当此编译器错误停止构建时,我正在将一些旧代码移植到 VS 2015:

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

转到相应的文件和行,我看到了:

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

GetFullModel并且SetFullModel是两个不同类中成员变量的 getter/setter 对:

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;}

是的,有些事情是错的。应该是dlg.GetFullModel指向成员函数的指针吗?我认为那些使用类名,而不是实例。更不用说这对执行语义意味着什么......

C++ 对我来说还是比较新的,所以我尝试了谷歌。它有很多函数指针,但它们看起来都与我的不同:

&OptDlg::GetFullModel // Standard-compliant

对比

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

对比

dlg.GetFullModel // ?

只是dlg.GetFullModel获取指向成员函数的指针的另一种方式吗?如果没有,什么是“标准 C++ 版本”,如果有的话?这只是那些 VS 6“扩展”中的另一个吗?

4

2 回答 2

5

&OptDlg::GetFullModel // Standard-compliant

如果您的参数类型应该采用成员函数,那就是您要使用的。但他们接受布尔值。看起来您只是在函数调用中缺少括号,它应该是:

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

可能有人忽略了警告(或没有警告),因此指针值(通过任何阴暗的手段产生)总是被解释为非 NULL,因此布尔值为真。

这只是那些 VS 6“扩展”中的另一个吗?

情况似乎是这样,尽管此评论是我能找到的唯一有据可查的证据,这是一个有意/广告的“功能”。没有看到任何关于它被添加或删除的正式公告。

于 2016-10-24T18:05:14.960 回答
4

在我看来,它非常像有人输入错误dlg.GetFullModel()(会调用该函数),而不是他们试图获取成员函数指针。

据推测,遗留编译器让它滑动,在不使用的情况下获取函数的地址&并将非空函数指针转换为bool(值为真)以传递给 set 函数。

于 2016-10-24T18:04:15.503 回答