C++11新機能-キーワードnullptrの導入
2547 ワード
1.nullptr導入の理由
nullptrを導入した理由はNULLから.CとC++プログラマーにとって、NULLに慣れていないに違いない.しかしCとC++のNULLは等価ではない.NULLはポインタがオブジェクトを指さないことを示すが、問題はNULLがキーワードではなくマクロ定義(macro)であることである.
1.1 NULLのCでの定義
Cでは、NULLはvoid*ポインタ値0として定義されます.
ただし、NULLを整数0として定義することもできます.
1.2 NULLのC++での定義
C++では、NULLは整数0として明確に定義されています.
1.3 C++がNULL上で不完全な互換性Cを選択した理由
根本的な原因はC++のリロード関数と関係がある.C++はマッチングパラメータのメカニズムを探索することによって最適マッチング(best-match)の関数を見つけようとするが,void*の暗黙型変換をサポートし続けると意味二義性(syntax ambiguous)の問題をもたらす.
2.nullptrの適用シーン
2.1コンパイラ
コンパイラがnullptrをサポートしている場合は、NULLのマクロ定義の代わりにnullptrを直接使用する必要があります.正常に使用する過程で彼らは完全に等価です.コンパイラの場合、Visual Studio 2010はnullptrを含むC++0 xのほとんどの特性をサポートし始めました.VS 2010以前のバージョンでは、このキーワードはサポートされていません.Codeblocks10.5付属のG++4.4.1 nullptrはサポートされていません.4.6.1にアップグレードするとnullptrをサポートできます(-std=c++0 xコンパイルオプションまたは-std=c++11をオンにする必要があります).
2.2使用方法
0(NULL)とnullptrは、次の例でスワップできます.
次の例ではnullptrを整形に割り当てることはできません.
nullptrはNULLよりも厳しいことがわかります.
上記のリロードの問題はnullptrを使用するとchar*が呼び出されます.
3.シミュレーションnullptrの実現
一部のコンパイラでは、c++11の新しいキーワードnullptrがサポートされていません.nullptrを実装するシミュレーションもできます.
nullptrを導入した理由はNULLから.CとC++プログラマーにとって、NULLに慣れていないに違いない.しかしCとC++のNULLは等価ではない.NULLはポインタがオブジェクトを指さないことを示すが、問題はNULLがキーワードではなくマクロ定義(macro)であることである.
1.1 NULLのCでの定義
Cでは、NULLはvoid*ポインタ値0として定義されます.
#define NULL (void*)0
ただし、NULLを整数0として定義することもできます.
1.2 NULLのC++での定義
C++では、NULLは整数0として明確に定義されています.
// lmcons.h NULL
#ifndef NULL
#ifdef __cplusplus
#define NULL 0
#else
#define NULL ((void *)0)
#endif
#endif
1.3 C++がNULL上で不完全な互換性Cを選択した理由
根本的な原因はC++のリロード関数と関係がある.C++はマッチングパラメータのメカニズムを探索することによって最適マッチング(best-match)の関数を見つけようとするが,void*の暗黙型変換をサポートし続けると意味二義性(syntax ambiguous)の問題をもたらす.
//
void foo(int i);
void foo(char* p)
foo(NULL); // which is called?
2.nullptrの適用シーン
2.1コンパイラ
コンパイラがnullptrをサポートしている場合は、NULLのマクロ定義の代わりにnullptrを直接使用する必要があります.正常に使用する過程で彼らは完全に等価です.コンパイラの場合、Visual Studio 2010はnullptrを含むC++0 xのほとんどの特性をサポートし始めました.VS 2010以前のバージョンでは、このキーワードはサポートされていません.Codeblocks10.5付属のG++4.4.1 nullptrはサポートされていません.4.6.1にアップグレードするとnullptrをサポートできます(-std=c++0 xコンパイルオプションまたは-std=c++11をオンにする必要があります).
2.2使用方法
0(NULL)とnullptrは、次の例でスワップできます.
int* p1 = 0;
int* p2 = NULL;
int* p3 = nullptr;
if(p1 == 0) {}
if(p2 == 0) {}
if(p3 == 0) {}
if(p1 == nullptr) {}
if(p2 == nullptr) {}
if(p3 == nullptr) {}
if(p1 == p2) {}
if(p2 == p3) {}
if(p1) {}
if(p2) {}
if(p3) {}
次の例ではnullptrを整形に割り当てることはできません.
int n1 = 0; // ok
int n2 = NULL; //warning
int n3 = nullptr; // error
int n4 = (int)NULL; //ok
int n5 = (int)nullptr; //error
if(n1 == nullptr) {} // error
if(n2 == nullptr) {} // error
if(nullptr) {} // error
nullptr = 0 // error
nullptrはNULLよりも厳しいことがわかります.
上記のリロードの問題はnullptrを使用するとchar*が呼び出されます.
void foo(int) {cout << "int" << endl;}
void foo(char*) {cout << "pointer" << endl;}
foo(0); // calls foo(int)
foo(nullptr); // calls foo(char*)
3.シミュレーションnullptrの実現
一部のコンパイラでは、c++11の新しいキーワードnullptrがサポートされていません.nullptrを実装するシミュレーションもできます.
const
class nullptr_t_t
{
public:
template<class T> operator T*() const {return 0;}
template<class C, class T> operator T C::*() const { return 0; }
private:
void operator& () const;
} nullptr_t = {};
#undef NULL
#define NULL nullptr_t