SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

Visual C++ Compiler November 2013 CTP: "Torino"でできること

  • X ポスト
  • このエントリーをはてなブックマークに追加

generic lambda

 lambda登場時から待ち望んでいた機能です。lambda引数の型を'auto'とすることで"汎用"のlambda式が書けるようになりました。

list14
auto add = [&](const auto& t, const auto& u) { return t + u; };
cout << add(10,4) << endl;
cout << add(string("じゅう"), "よん") << endl;

 ただしTorinoでは暗黙のキャプチャ、すなわち[&]や[=]を使うと"本リリースではサポートされていませんゴメンナサイ"エラーとなってしまいます。generalized lambda captureと共に、ちゃんと動くようになるまでしばらくのガマンです。

resumable/await

 最後に紹介するresumable/awaitは、C++17に提案されている非同期処理のためのできたてホヤホヤの機能。C#なみなさんにはasync/awaitでおなじみです。

 resumable/awaitはC++/CXによるストアアプリでその有用さが実感できます。

 ストアアプリでは時間のかかる処理に引きずられてUIの反応が鈍るのを徹底的に排除しています。時間のかかりそうな処理を行うAPIはことごとく、メソッド名に"~Async"が付いていて、その制御は結果が得られるのを待たずに呼び出し元に戻ってきます。"非同期処理"ってやつですね。それじゃ結果が得られたときの処理がどうするか……結果が得られたときに行う処理をコールバックに登録しておくというカラクリになっています。

 「"背景色変更ボタン"が押されたらダイアログをpop-upし、好みの色をユーザに選ばせる」サンプルを書いてみました。

 ボタン・クリックのハンドラはこんなコードになります。

list15
void MainPage::OnButtonClick(Object^ sender, RoutedEventArgs^ args)
{
    MessageDialog^ msgdlg = ref new MessageDialog(L"どの色がお好き?", L"背景色の変更");
    msgdlg->Commands->Append(ref new UICommand(L"赤", nullptr, Colors::Red));
    msgdlg->Commands->Append(ref new UICommand(L"緑", nullptr, Colors::Green));
    msgdlg->Commands->Append(ref new UICommand(L"青", nullptr, Colors::Blue));

    // Show the MessageDialog
    task<IUICommand^> showTask = create_task(msgdlg->ShowAsync());
    showTask.then(
        // ShowAsyncが完了した後の処理は callback で書かにゃならん
        [this](IUICommand^ command) {
            // Get the Color value
            Color clr = safe_cast<Color>(command->Id);
            // Set the background brush
            contentGrid->Background = ref new SolidColorBrush(clr);
        }
    );
}

 背景色変更ボタンが押されたことに反応するイベントハンドラ内のmsgdlg->ShowAsync()でダイアログがpop-upするのですが、その結果が得られることなくすぐさまShowAsync()から戻ってきてしまいます。結果が得られた(ユーザが色を選択した)時の処理(callback)はtask.then()の引数に与えているlambda式です。

 この例ではさほどにややこしくはありませんが、非同期APIをいくつも呼ぶことで所望の動作を行う、例えばファイルを開けて/"一行読む"を繰り返して/ファイルを閉じるような場合、何段ものlambdaの入れ子になってしまいます。

 Torinoで追加されたresumable/awaitを使うと、"見かけ上"callbackが消えてしまい、上から下に一連の処理を書きおろすことができます。

list16
void MainPage::OnButtonClick(Object^ sender, RoutedEventArgs^ args) __resumable
{
    MessageDialog^ msgdlg = ref new MessageDialog(L"どの色がお好き?", L"背景色の変更");
    msgdlg->Commands->Append(ref new UICommand(L"赤", nullptr, Colors::Red));
    msgdlg->Commands->Append(ref new UICommand(L"緑", nullptr, Colors::Green));
    msgdlg->Commands->Append(ref new UICommand(L"青", nullptr, Colors::Blue));

    // Show the MessageDialog
    IUICommand^ command = __await msgdlg->ShowAsync(); // 「ここで待ってる」かのように書きおろせる!
    Color clr = safe_cast<Color>(command->Id);
    contentGrid->Background = ref new SolidColorBrush(clr);
}

 resumable/awaitのアタマに付いてる'__'は、コンパイラ/ライブラリベンダー独自のもので標準ではないことを表しています。resumable/awaitはC++17に提案された機能/構文で、国際標準として正式に採用されるかは定かではなく、このままずーっと'__'が付いたままとなるかもしれません……。

 以上、Visual C++の今後を垣間見ることのできるVisual C++ Compiler November 2013 CTP:Torinoの主要新機能ご紹介でした。

 マイクロソフトの開発計画によれば、Visual Studio製品群は以前よりずっと短いスパンでUpdateや改版が行われるとのこと。

 .NETが華やかなVisual Studioですが、C++にも頑張ってもらいたいですね。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

επιστημη(エピステーメー)

C++に首まで浸かったプログラマ。Microsoft MVP, Visual C++ (2004.01~2018.06) "だった"りわんくま同盟でたまにセッションスピーカやったり中国茶淹れてにわか茶...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/7598 2014/03/04 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング