41

C++98 では、null ポインターはリテラル0(または、実際には値がゼロの任意の定数式) で表されていました。C++11 では、nullptr代わりに優先します。ただし、これは純粋な仮想関数では機能しません。

struct X
{
    virtual void foo() = nullptr;
};

これが機能しないのはなぜですか?それは完全に意味をなさないでしょうか?これは単なる見落としですか?修正されますか?

4

8 に答える 8

46

構文が0, notまたはその他の非終端一致nullptr.

常に機能しているだけ0です。0L構文と一致しないため、形式が正しくありません。

編集

Clang は= 0x0= 0b0および= 00(31.12.2013) を許可します。もちろん、これは誤りであり、コンパイラで修正する必要があります。

于 2013-12-31T17:52:31.423 に答える
30

関数の= 0表記virtualは文字通り「null を割り当てる」ではなく、実際には欺瞞的な特別な表記でした: 純粋な仮想関数も実装できます。

さまざまなコンテキスト キーワードを使用する場合は、コンテキスト キーワードにするabstractよりも許可する方が理にかなって= nullptrabstractます。

于 2013-12-31T17:54:10.587 に答える
17

これはまさに文法がどのように定義されているかです。ドラフト C++ 標準セクション9.2 クラス メンバーを見ると、関連する文法は次のようになります。

[...]
member-declarator:
 declarator virt-specifier-seqopt pure-specifieropt
[...]
pure-specifier:
  = 0
  ^^^

文法は、pure-specifier整数リテラル= 0ではないことを明確に示しています。次のようなことを試みた場合:

virtual void foo() = 0L;

また:

virtual void foo() = NULL ;

gcc私に言います:

エラー: ';' の前の純粋な指定子が無効です ('= 0' のみが許可されます)。トークン

そしてclang言います:

エラー: 関数の初期化子が純粋な指定子のように見えません

以下は両方で機能しますが:

#define bar 0
//...
virtual void foo() = bar;

また、 8 進リテラル、16 進リテラル2リテラルのclangゼロが許可されているようですが、これは正しくない動作です。

アップデート

どうやら、、などを含むゼロの整数リテラルVisual Studio受け入れるようです...ただし、 は受け入れません。NULL0L0x000nullptr

于 2013-12-31T17:57:10.380 に答える
6

この= 0構文は、ポインターを初期化するために使用されたのではなく、単に提供されたものvirtualが純粋であることを構文的に示すためのものでした。

したがって、= 0純粋なvirtuals を宣言するための構文は変更されていません。

于 2013-12-31T17:53:17.647 に答える
6

ポイント全体nullptr(またはポイントの大部分)は、ポインターにのみ割り当てる(または初期化に使用する)ことができるということです。

この場合、ポインタの初期化や代入を行っていないため、この状況で使用できるという意味さえありません。

于 2013-12-31T17:56:58.800 に答える
1

C++11 文法では、0ここでのみ許可されます (ポインターを意味しません)。nullptrではないので、0失敗します。が定義されてNULLいる場合にのみ機能します(常にそうであるとは限りません)。ここで使用するか、次の定義を使用します (ポインターではない場合に本当に null を使用する場合)。NULL00

#define VIRTUAL_NULL 0
struct X
{
    virtual void foo() = VIRTUAL_NULL;
};
于 2013-12-31T20:04:57.460 に答える