サブロウ丸

Sabrou-mal サブロウ丸

主にプログラミングと数学

master mind by c++; part2 auto & decltype

今回やること

auto

autoc++11から導入された型推論機能で, c++14, c++17ではその適用範囲が増えました. c++17を使用することを前提に例を紹介します.

関数の返り値

Code guess = policy(S, S);
auto guess = policy(S, S);

コンテナの部分for文

for ( Code code : S )
for ( auto code : S )
for ( auto const &code : S )  # 要素のコピーなし

関数の返り値の型

Code policy(
      CodeList &S,
      CodeList &G
      )
{
   // random sampling from G
   std::mt19937 engine(0);
   std::uniform_int_distribution<> sampler(0, G.size()-1);
   Code guess = G[sampler(engine)];
   return guess;
}
auto policy(
      CodeList &S,
      CodeList &G
      )
{
   // random sampling from G
   std::mt19937 engine(0);
   std::uniform_int_distribution<> sampler(0, G.size()-1);
   auto guess = G[sampler(engine)];
   return guess;
}

などなど.

decltype

decltypeは関数の返り値の型を取得する機能で, templateの作成時に使用されることが多いようですね.

例えば下記のコードについて, while文のネスト(中身)でguessが定義されているため, while文の外でguessを定義したいとします.

   while( S.size() > 1 )
   {
      auto guess = policy(S, S); // guessをwhileの外で定義したい
      trial(S, guess);           // update S
   }

ダメな例. これではguess変数型が推論できないと, コンパイル時に表示されます.
error: declaration of variable 'guess' with deduced type 'auto' requires an initializer

   auto guess; // 外に出してみた
   while( S.size() > 1 )
   {
      guess = policy(S, S);
      trial(S, guess);           // update S
   }

そこで, policyの返り値の型をdecltype(policy(S, S))で取得します. これはコンパイル時に関数の返り値の型に置き換わるため, 実際に関数policy(S, S)が実行されることはありません.

   decltype(policy(S, S)) guess;  // Code guessと同義
   while( S.size() > 1 )
   {
      guess = policy(S, S);   // G <- S
      trial(S, guess);        // update S
   }

まとめ

autoとdelctypeを導入しました.
本記事では, autoにできるところはほぼ変えてしまいましたが, 型推論を使わない方が良い場面も当然あります. ( C++ autoの使いどころ・使わない方が良い場面 - uchan note ).
またc++20では, 関数のパラメタ型にもautoが使えるようになっています. ( 4つのauto、4つのC++規格 - Qiita ) 実際私の環境でも使えるようになっていました.

コード

参考

他の記事