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(...

GetFullModelSetFullModelは、2 つの異なるクラスのメンバー変数の 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++ はまだ比較的新しいので、Google を試してみました。関数ポインターがたくさんありましたが、それらはすべて私が持っていたものとは異なって見えました:

&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 の「拡張機能」の 1 つにすぎませんか?

4

2 に答える 2

5

&OptDlg::GetFullModel // Standard-compliant

パラメーターの型がメンバー関数を取ることになっている場合は、それを使用します。しかし、それらはブール値を取ります。関数呼び出しで括弧が欠落しているように見えますが、次のようにする必要があります。

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

おそらく、誰かが警告を無視していた (または警告を表示していなかった) ため、ポインター値 (怪しげな手段で生成されたもの) は常に非 NULL として解釈されていたため、ブール値は true でした。

これは VS 6 の「拡張機能」の 1 つにすぎませんか?

このコメントは、意図的/宣伝された「機能」であることがわかる唯一の文書化された証拠ですが、そのように見えます。追加または削除されたという正式な発表はありません。

于 2016-10-24T18:05:14.960 に答える
4

メンバー関数ポインターを取得しようとしていたのではなく、誰かがタイプミスした (関数を呼び出す)ように強く見えます。dlg.GetFullModel()

おそらく、従来のコンパイラはそれをスライドさせ、使用せずに関数のアドレスを取得し、&null 以外の関数ポインターをbool(値は true で) 変換して set 関数に渡します。

于 2016-10-24T18:04:15.503 に答える