SHOEISHA iD

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

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

特集記事

「Visual C++ Compiler November 2012 CTP」で追加された6つの新機能

追加されるC++11の機能

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

 「Visual C++ Compiler November 2012 CTP」で追加されたC++11の6つの機能を紹介します。

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

はじめに

 昨年の末、新たなVisual C++がリリースされたことにお気づきでしょうか。

 CTPとはCommunity Technology Preview、要するにお試し版、正式なupdateまでの"つなぎ"なので実プロジェクトで使うわけにはいかないけども「次版の予告編として提供するから遊んでみてね。ついでに不具合見つけたら教えてくれるとうれしいな♪」的なリリースです。

 Nov2012CTPで提供されるのは、コンパイラ本体とヘッダが一本。Visual Studio 2012にadd-inする形式で、CTP単体ではインストールしても無意味です。Visual Studio 2012(無償版:Expressも可)がインストールされた環境で本CTPをインストールするとVisual C++プロジェクト・プロパティのプラットフォーム・ツールセットに追加され、こいつを選択することでコンパイラが切り替わります。

 ただし今回のCTPはホントにコンパイラ"だけ"であり、IDEやIntelliSenseは従来のまま。なので、構文エラーを示す波線がところどころに現れるのはご承知おきください。

 Nov2012CTPで追加されたのは、VC11(Visual C++ 2012)でサポートできてなかったC++11の機能の中から6つ:

  • Raw String Literals
  • Explicit Conversion Operators
  • Default template Arguments for Function Templates
  • Delegating Constructors
  • Uniform Initialization
  • Variadic Templates

 片っ端からざっくりと解説しましょうね。

Raw String Literals:'生'の文字列リテラル

 C/C++の文字列リテラルはバックスラッシュ:'\'によって特殊な文字を表現できます。\nで改行、\tでTabとかね。その代わり \ は\\ と表記しなければなりませんが、これが時として煩わしく感じることがあります。例えば正規表現。”バックスラッシュで囲まれた部分文字列”を見つけたいとき、これにマッチする正規表現は\\.*\\です。これを文字列リテラルで記述すると例えば:

  regex re( "\\\\.*\\\\" );

 です。ちょっとウンザリしますね。C++11ではリテラルにRを接頭することでバックスラッシュによるエスケープを行わない'生'の文字列を書き下すことができます。

  regex re( R"(\\.*\\)" );

 このように、R"(と)" で囲まれた文字列がリテラルとなり、改行やTab、引用符などもそのまま書き下せます。...それじゃリテラル中に )" を書きたい...そんなアナタのために、終端記号をユーザが指定できます。R"raw(abc"(def)"ghi)raw"のようにR"○×△(からはじめれば)○×△"が終端です。なるほどねー。

Explicit Conversion operators:明示的な変換オペレータ

list-01
#include <iostream>

using namespace std;

class negative {
public:
  negative(int v) : value_(v) {}
  operator bool() const { return value_ < 0; }
private:
  int value_;
};

int main() {
  negative neg(-3);
  cout << neg + 123 << endl; // えっ?
}

 このコード、不思議なことにコンパイル/実行できちゃいます。class negativeであるbegとint値123とを+できるハズがないのに...。これはoperator bool()によってboolへの暗黙の型変換が行われ、bool値がint扱いされて+されるからなんですね。

 このような暗黙の型変換を抑止するため、変換オペレータを'explicit'で修飾できるようになりました。引数1つのコンストラクタをexplicit修飾することで暗黙のコンストラクトを抑止するのと同じです。explicitされた変換オペレータは明示的なキャスト(この例では(bool)negやstatic_cast<bool>(neg))が行われない限り、勝手に変換されることはなく、コンパイルエラーとしてくれます。

Default Template Arguments for Function Templates:関数テンプレートにおけるデフォルト・テンプレート引数

 <algorithm>に定義された std::sort を用いてコンテナ内の要素をソートする関数を書くことにしましょう。引数はコンテナと比較オブジェクト(ファンクタ)、ただし比較オブジェクトが与えられないときはstd::less<コンテナ要素の型>を使います。従来ならこんな実装になるでしょうね:

list-02
template<typename Container, typename Pred>
void sort_container(Container& container, Pred compare) {
  std::sort(begin(container), end(container), compare);
}

template<typename Container>
void sort_container(Container& container) {
  std::sort(begin(container), end(container), std::less<typename Container::value_type>());
}

 関数テンプレートにデフォルト・テンプレート引数が許されないので、比較オブジェクトのアリ版とナシ版とを定義しています。C++11ではデフォルト・テンプレート引数がサポートされるため、こんなコードで実現できます。

list-03
template<typename Container, typename Pred = std::less<typename Container::value_type>>
void sort_container(Container& container, Pred compare =Pred()) {
  std::sort(begin(container), end(container), compare);
}

会員登録無料すると、続きをお読みいただけます

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

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

メールバックナンバー

次のページ
Delegationg Constructors:コンストラクタの移譲

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

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

もっと読む

この記事の著者

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

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

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

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

この記事をシェア

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

おすすめ

アクセスランキング

アクセスランキング

イベント

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

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

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

メールバックナンバー

アクセスランキング

アクセスランキング