C++98 では、null ポインターはリテラル0(または、実際には値がゼロの任意の定数式) で表されていました。C++11 では、nullptr代わりに優先します。ただし、これは純粋な仮想関数では機能しません。
struct X
{
virtual void foo() = nullptr;
};
これが機能しないのはなぜですか?それは完全に意味をなさないでしょうか?これは単なる見落としですか?修正されますか?
C++98 では、null ポインターはリテラル0(または、実際には値がゼロの任意の定数式) で表されていました。C++11 では、nullptr代わりに優先します。ただし、これは純粋な仮想関数では機能しません。
struct X
{
virtual void foo() = nullptr;
};
これが機能しないのはなぜですか?それは完全に意味をなさないでしょうか?これは単なる見落としですか?修正されますか?
構文が0, not式またはその他の非終端一致nullptr.
常に機能しているだけ0です。0L構文と一致しないため、形式が正しくありません。
編集
Clang は= 0x0、= 0b0および= 00(31.12.2013) を許可します。もちろん、これは誤りであり、コンパイラで修正する必要があります。
関数の= 0表記virtualは文字通り「null を割り当てる」ではなく、実際には欺瞞的な特別な表記でした: 純粋な仮想関数も実装できます。
さまざまなコンテキスト キーワードを使用する場合は、コンテキスト キーワードにするabstractよりも許可する方が理にかなって= nullptrいabstractます。
これはまさに文法がどのように定義されているかです。ドラフト 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
この= 0構文は、ポインターを初期化するために使用されたのではなく、単に提供されたものvirtualが純粋であることを構文的に示すためのものでした。
したがって、= 0純粋なvirtuals を宣言するための構文は変更されていません。
ポイント全体nullptr(またはポイントの大部分)は、ポインターにのみ割り当てる(または初期化に使用する)ことができるということです。
この場合、ポインタの初期化や代入を行っていないため、この状況で使用できるという意味さえありません。
C++11 文法では、0ここでのみ許可されます (ポインターを意味しません)。nullptrではないので、0失敗します。が定義されてNULLいる場合にのみ機能します(常にそうであるとは限りません)。ここで使用するか、次の定義を使用します (ポインターではない場合に本当に null を使用する場合)。NULL00
#define VIRTUAL_NULL 0
struct X
{
virtual void foo() = VIRTUAL_NULL;
};