忍者ブログ

どっかのゆとりのチラシの裏

plasma_effectのメモ帳的ブログのようなsomething

[PR]

×

[PR]上記の広告は3ヶ月以上新規記事投稿のないブログに表示されています。新しい記事を書く事で広告が消えます。

反省会

この記事はアドベントカレンダーの反省会的記事である。まずは以下のコードを見て欲しい。

このコードはill-formedだ。gccでもVC++でもそうである。
これはpush_back内部でunique_ptrのコピーコンストラクタを呼ぼうとしているからだ。
エラーメッセージ的にそうとしか考えられない。では次のコードはどうか。

これはwell-formedだ。gccでもVC++でもそうである。何が異なるか。

早い話が後者はpush_backの引数が無名オブジェクト、つまり右辺値であるのに対し
前者は普通のオブジェクト、つまり左辺値であるからだ。
前者ではpush_back(const type&)が呼ばれ後者ではpush_back(type&&)が呼ばれる。

要は右辺値についての説明がなければunique_ptrとSTLの連携については語れないわけで。
それがなかったため記事の一部を削除する羽目になったのである。

KMC関係者各位や該当記事を読んでいただいた方には申し訳なく思っている。
PR

C++11超入門

初めましての方は初めまして、そうでない方はこんにちは。DtYaZsKです。
この記事はKMC Advent Calendar 2013の22日目の記事です。
昨日はwackyさんの東アジア文字幅問題との戦いの記録でした。

今回はISO/IEC 14882:2011、通称C++11で追加されたC++の新しい要素の内私が独断と偏見で選んだものを5つほど簡単に説明します。
C++11超入門と銘打っていますがそれ以前のC++、所謂C++03までの知識、特にtemplateとポインタとSTLの基礎知識は前提としています。
怖いC++erの方々にとってはすでに知ってる内容ですし、逆にC++のことがさっぱりな方にとっては意味不明な内容かもしれません。
今回やる内容はgccやclangではもちろん、VC++でも使うことが出来ます。そのため最近のC++コンパイラならすぐに使えるものばかりです。(VC++はC++のコンパイラではないというツッコミは今回放置しておきます。)
最新のコンパイラを用意するのが面倒な方にも朗報です。今の時代はオンラインコンパイラが存在するのですぐに最新のC++を体感することができます。私はWandboxをよく使っています。
また標準ライブラリのリファレンスはcpprefjpをよく使っています。今回の記事はこのページを参考にしました。

12/22 23:55追記 記事の一部が間違っていることに今更気づいたので該当部分を削除しました

1.スマートポインタ
newで動的にメモリを確保した時それを解放するためにdeleteを書くのは面倒ですし書き忘れでメモリリークを起こすと大変です。
不要なメモリを自動で開放してくれる仕組みがあればそのような問題を解決できます。
そのような仕組みを持つ賢いポインタをスマートポインタといいます。
C++11にはスマートポインタであるshared_ptrとunique_ptrが存在します。
これら2つのクラスは共にmemoryヘッダをincludeすることで使えるようになります。
共にコンストラクタでポインタを受け取りますが

shared_ptrには補助関数がありそちらの方が効率的です。

ヌルポインタでないポインタを保持している場合デストラクタで条件を満たせば開放します。
これら2つの違いはコピー可能かどうかです。
shared_ptrは参照カウント方式のスマートポインタです。すなわち自分が参照されている数をカウントし0になったら自動で開放します。

一方unique_ptrはコピー不可能なスマートポインタです。コピーしようとするような文が含まれている場合コンパイルエラーとなります。よってデストラクタで確実に開放します。(ヌルポインタ保持時除く)

shared_ptr同士、unique_ptr同士なら中身を交換できますし

中身をリセットすることもできます。

要素のアクセスについてですがoperator->とoperator*がオーバーロードされているので普通のポインタのように要素にアクセスできます。
 
関連した話でC++11ではヌルポインタ専用リテラルnullptrが追加されています。


なお今回weak_ptrの説明は省きました。
またC++14ではmake_sharedのunique_ptr版、make_uniqueが追加されます。

2.array
STLに静的配列が追加されました。arrayです。いうならば普通の配列のラッパーです。arrayヘッダをincludeすることで使えます。
テンプレート引数で格納する型と要素数を指定できます。

使い方も普通の配列と変わりません。

配列でなくてarrayを使う利点はalgorithmヘッダの関数を用いることができることです。

他にも要素をまるまる入れ替えたり範囲チェックつきアクセスも出来ます。


3.randomヘッダ
Cの時代から擬似乱数生成の関数は存在しました。randです。この関数には2つ問題点がありました。
一つは生成される数値の範囲が狭いこと。もう一つは線形合同法を用いているため結果のランダム性が低いこと。
C++11では独自の擬似乱数生成法を持つことができました。それがrandomヘッダです。
randomヘッダでは擬似乱数生成のためのクラスが用意されています。
例えばmt19937クラスはメルセンヌツイスター法で32bit長符号なし整数型乱数を生成します。

初期化にはrandom_deviceクラスを用いることが出来ます。これはハードウェアの状態によって決める本物の乱数です。

ハードウェアの情報を読み取るためrandom_deviceはその他の乱数生成クラスに比べ遅めです。
よってメインでは擬似乱数生成クラスを用い、初期化にはrandom_deviceを使うのが一つの定型です。

他にもrandomヘッダには上のような擬似乱数生成クラスを用いたオプションが用意されています。
例えばuniform_int_distributionクラスは指定範囲の整数を等確率で返してくれます。

bernoulli_distributionは指定された確率でtrueを、trueでないときはfalseを返してくれます。

他にもrandomヘッダには様々なクラスが存在しますが、全てを紹介するには時間が足りません。

4.autoとdecltype
しばしば型の名前を書くのが面倒になるような型が存在します。
C++11ではコンパイラが型を判別し自動で変数、または関数の型を決定してくれる方法が2つ存在します。
もう一つはauto、もう一つはdecltypeです。
autoは=の右辺値の型によって左辺値の型を決定します。一方decltypeは関数に似た使い方をし引数として渡されたオブジェクトやリテラルによって型を決定します。
以下を見ればだいたい理解できると思います。


5.範囲ベースのfor文
配列の要素に対して1つずつ同じ処理をしていきたい時があります。
別に普通のfor文を使えばいいのですがカウント用の変数を使わないなら範囲外アクセスが怖いだけですよね。
C++11では配列の範囲を基準とした新たなfor文ができました。
使い方は以下を見ればわかると思います。

配列だけでなくSTLにも使えます。

参照でない場合は要素をそれぞれコピーして処理します。


C++11では言語仕様も標準ライブラリもC++03に比べはるかに強化されました。
今回の記事で扱った内容でもまだまだ氷山の一角です。
C++11の全てを扱うにはこのブログではキャパ不足かもしれません。
この記事をきっかけに少しでもC++11について学ぼうと考える方が増えることが私の願いです。

明日はhatsusatoさんのC++11で覚醒した共用体の話です。

constについての検証

C++ではconstというキーワードが存在する。
定数を作るアレなのだが少しややこしいことが起きた。
例えば以下のコードは通る

const int a = 1;
static_assert(a,"");

int main()
{

}

一方で以下のコードは通らない

int func(){return 1;}
const int a = func();
static_assert(a,"");

int main()
{

}

何が違うのかというと前者は初期化でリテラルを渡していたのに対し後者は関数の返り値で初期化している。このとき前者ではコンパイル時定数だが後者は実行時定数となる。わけがわからない。
後者は実行時に評価されるからいいとして前者はホントにどういうことなのか。
まぁコンパイル時定数になってくれないとTMPは成立しないから別にいいのだが。

カレンダー

10 2024/11 12
S M T W T F S
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30

フリーエリア

最新CM

[02/12 kariya_mitsuru]
[10/14 どっかの京大生o]
[10/04 どっかのZ会生y]
[07/31 どっかのZ会生y]
[07/31 GNR]

プロフィール

HN:
plasma_effect
性別:
非公開

バーコード

ブログ内検索

最古記事

(06/08)
(06/18)
(06/21)

P R