web-dev-qa-db-ja.com

nullptrをgccでエミュレートできますか?

nullptrがVisual Studio 2010に実装されていることを確認しました。このコンセプトが気に入ったので、できるだけ早く使い始めたいです。ただし、GCCはまだサポートしていません。私のコードは両方で実行する必要があります(他のコンパイラでコンパイルする必要はありません)。

それを「エミュレート」する方法はありますか?何かのようなもの:

#define nullptr NULL

(それは明らかにまったくうまくいかないでしょう、それは私が何を意味するかを示すためだけです。)

48
nuzz

公式提案 には回避策があります-

const                        // this is a const object...
class {
public:
  template<class T>          // convertible to any type
    operator T*() const      // of null non-member
    { return 0; }            // pointer...
  template<class C, class T> // or any type of null
    operator T C::*() const  // member pointer...
    { return 0; }
private:
  void operator&() const;    // whose address can't be taken
} nullptr = {};              // and whose name is nullptr
61
N 1.1

Gccは 4.6 の時点でnullptrをサポートしているようです。

9

また、gcc(実際にはg ++)には、何年も__nullという拡張機能がありました。 nullptrの提案が出されたとき、これは業界の実装経験としてカウントされました。

__null拡張機能は、特殊なケースを検出し、ポインターパラメーターに渡されることを意図していたときに、ブールパラメーターに誤ってNULLを渡すなどの警告を出します(関数に加えられた変更、呼び出し側の適応を忘れた)。

もちろん、これは移植可能ではありません。上記のテンプレートソリューションは移植可能です。

6
emsr

Gcc 4.6.1(Ubuntu 11.11 oneiric)に見え、nullptrが追加されました。

私のhpp/cppファイルの迅速で再帰的なsedの検索と置換は、私にとってはうまくいきました。

find . -name "*.[hc]pp" | xargs sed -i 's/NULL/nullptr/g'
5
kfmfe04

-std = c ++ 0xを忘れた可能性があります。私のMingwバージョンのgccは4.6.1/4.7.1で、どちらもnullptrをサポートしています。

「c ++標準ライブラリ、チュートリアルとリファレンス、2番目」の説明によると、nullptrはキーワードであり、整数型ではなく各ポインタ型に自動的に変換できます。これにより、次のオーバーロード関数があいまいなNULLの欠点が克服されます。 :void f(int); void f(void *);

f(NULL); //あいまいなf(nullptr); // OK

VC2010でこの機能をテストすると、MSDNドキュメントが実際のコンパイラと競合することが示されています。

Nullptrキーワードはタイプではなく、以下での使用はサポートされていません。

のサイズ

タイプID

nullptrをスローする

実際、VC2010では、上記の演算子/式はすべて正当です。 sizeof(nullptr)結果4. typeid.name()結果std :: nullptr_t、およびスローnullptrは、 "const void *"および "void *"(およびその他のポインター型)でキャッチできます。

Gcc(4.7.1)はnullptrに関してより厳密に見えますが、nullptrのスローは「void *」ではキャッチできず、「...」でキャッチできます

2
zhaorufei