C++11とは
かつてC++0xと呼ばれたC++11は、現行のC++言語の拡張および改訂版です。 C++11には、コア言語の新機能が含まれるだけでなく、C++標準ライブラリが拡張され、C++技術報告1ライブラリの大部分が組み込まれています。
C++11には、ラムダ式、型派生キーワードauto、decltype、テンプレートの改良など、多数の新機能が含まれています。
この記事では、上記のC++11の新機能を簡単に説明し、C++11がC++の使いやすさの面で果たす大きな役割をすぐに理解していただけるようにします。
新しいキーワード
オート
auto*** 種の役割は、自動型導出のために C++11 で導入されました。
Autoの自動型導出は、初期化式から変数のデータ型を推測するために使用されます。autoの自動型派生により、プログラミングが大幅に簡素化されます。
autoは変数の型派生を実際にコンパイルするので、プログラムの効率に悪影響を与えることはありません。
また、コンパイルは右サイドでも導出し、それが左サイドと一致するかどうかを判断しなければならなかったはずなので、autoはコンパイル速度には影響しないようです。
auto a; // エラー、autoは初期化式による型推論である。
auto i = 1;
auto d = 1.0;
auto str = "Hello World";
auto ch = 'A';
auto func = less<int>();
vector<int> iv;
auto ite = iv.begin();
auto p = new foo() // カスタム型の型派生
自動だけでなく、上記のアプリケーションを持って、それはまた、テンプレートでは、製品の例の処理の次の例など、非常に便利ですが、自動を使用しない場合は、テンプレートパラメータを宣言する必要があります製品:
template <typename Product, typename Creator>
void processProduct(const Creator& creator) {
Product* val = creator.makeObject();
// do somthing with val
}
.
autoを使う場合は、次のように書きます:
template <typename Creator>
void processProduct(const Creator& creator) {
auto val = creator.makeObject();
// do somthing with val
}
面倒なテンプレート・パラメーターを捨てることで、コード全体がより直交的になります。
宣言型
autoは変数を宣言し、decltypeは変数や式から型を取得します:
int x = 3;
decltype(x) y = x;
一部の人々は、decltypeは、それの実用的な側面は、上記の例では、続行するには、製品を処理する上記の例では、戻り値として製品を使用する場合は、それを行うにはどうですか?このように書くことができます:
template <typename Creator>
auto processProduct(const Creator& creator) -> decltype(creator.makeObject()) {
auto val = creator.makeObject();
// do somthing with val
}
ヌルプトル
void F(int a){
cout<<a<<endl;
}
void F(int *p){
assert(p != NULL);
cout<< p <<endl;
}
int main(){
int *p = nullptr;
int *q = NULL;
bool equal = ( p == q ); // equaltrueの値は、pとqの両方がヌル・ポインタであることを示す。
int a = nullptr; // コンパイル失敗、nullptrはintに変換できない
F(0); // ++98C言語におけるコンパイルの失敗と二重性; C言語におけるコンパイルの失敗++11でFを呼び出す
F(nullptr);
return 0;
}
順次ループ
C++のforループは、Javaの簡略化されたforループと同様に使用することができ、配列、コンテナ、文字列、およびシーケンスで定義されたbegin関数とend関数によってトラバースするために使用することができます、サンプルコードは次のとおりです:
map<string, int> m{{"a", 1}, {"b", 2}, {"c", 3}};
for (auto p : m){
cout<<p.first<<" : "<<p.second<<endl;
}
ラムダ式
ラムダ式はJavascriptのクロージャに似ており、プログラミングを簡素化するために匿名関数オブジェクトを作成・定義するために使用することができます:
[関数オブジェクトの引数]->返り値型{関数本体}。
vector<int> iv{5, 4, 3, 2, 1};
int a = 2, b = 1;
for_each(iv.begin(), iv.end(), [b](int &x){cout<<(x + b)<<endl;}); // (1)
for_each(iv.begin(), iv.end(), [=](int &x){x *= (a + b);}); // (2)
for_each(iv.begin(), iv.end(), [=](int &x)->int{return x * (a + b);});// (3)
- の中の引数は、ラムダ式で取得できるグローバル変数を指します。関数のbは、その関数がLambda式の外部でグローバル変数を取得できることを意味し、[]内に=を渡すと、同じLambda式内の変数など、すべての外部変数を取得することができます。
- () 内の引数は、関数が呼び出されるたびに渡されるものです。
- -> 例えば、int型の変数が返されます。
可変長パラメータのテンプレート
C++ではペアを使用していますが、make_pairコンストラクタを使用してペアを構築し、2つの異なる型のデータを含むコンテナを構築することができます。たとえば、次のコードです:
auto p = make_pair(1, "C++ 11");
C++11で可変長パラメータ・テンプレートが導入されたため、新しいデータ型が考案されました。
auto t1 = make_tuple(1, 2.0, "C++ 11");
auto t2 = make_tuple(1, 2.0, "C++ 11", {1, 0, 2});
こうすることで、ペアをペアの中に入れ込むような古い醜い慣習を避け、すっきりとしたコードになります。
C言語ではprintfに複数の引数を渡すことができますが、C++11では可変長の引数テンプレートを使用することで、より簡潔なPrint関数を実現することができます。
template<typename head, typename... tail>
void Print(Head head, typename... tail) {
cout<< head <<endl;
Print(tail...);
}
Printでは、以下のようにいくつかの異なる種類のパラメータを渡すことができます:
Print(1, 1.0, "C++11");
よりエレガントな初期化メソッド
C++11 の導入により、初期化リストを使用できるのは配列のみとなり、その他のコンテナは初期化リストを使用する場合にのみ以下のメソッドを使用できます:
int arr[3] = {1, 2, 3}
vector<int> v(arr, arr + 3);
C++11 では、 置換に次の構文を使用で き ます:
int arr[3]{1, 2, 3};
vector<int> iv{1, 2, 3};
map<int, string>{{1, "a"}, {2, "b"}};
string str{"Hello World"};
そして...
C++11のエキサイティングな新機能についてもっと知りたい方には、以下の2つのブログをお勧めします: