SlideShare a Scribd company logo
C++0x
      言語の未来を語る




高橋 晶(アキラ)
Blog: Faith and Brave – C++で遊ぼう


        わんくま同盟 東京勉強会 #22
Agenda
•   What’s C++0x
•   Angle Bracket
•   Initializer List
•   auto
•   decltype
•   Delegating Constructor
•   Extending sizeof
•   Raw String Literal
•   Defaulted and Deleted Functions
•   Member Initializers
•   nullptr
•   constexpr
•   Template Aliases
•   static_assert
•   Variadic Templates
•   Concept
•   Range-base for loop
•   RValue Reference・Move Semantics
•   Lambda Expression
•   New Function Daclarator Syntax




                             わんくま同盟 東京勉強会 #22
What’s C++0x (C++0xってなに?)

• C++の次バージョン(現在はC++03)

• 「0x」とは200x年の意味で、C++09を目指している
  (もしかしたら C++10 になっちゃうかも)

• エキスパートよりも初心者のための言語拡張を行う




            わんくま同盟 東京勉強会 #22
Angle Bracket(山カッコ)

• C++03では以下のコードはコンパイルエラーになる

vector<basic_string<char>> v;
                   // エラー! operator>> が使われている



• 連続した山カッコがシフト演算子と判断されてしまう
• C++0xではこの問題が解決される




                わんくま同盟 東京勉強会 #22
Initializer List(初期化子リスト)

• ユーザー定義クラスで配列のような初期化を可能にする
• Bjarne氏曰く「何で今までできなかったのかわからない」
• std::initializer_listクラスを使用する

// 初期化
vector<int> v = {3, 1, 4};

// 戻り値
vector<int> factory() { return {3, 1, 4}; }

// 引数
void foo(const vector<int>& v) {}
foo({3, 1, 4});


                     わんくま同盟 東京勉強会 #22
auto

• 型推論
• autoキーワードの意味が変更になる(めずらしい)
• autoで宣言された変数の型は右辺から導出される

vector<int> v;
vector<int>::iterator it = v.begin(); // C++03
auto                  it = v.begin(); // C++0x

const/volatile修飾や、参照(&)・ポインタ(*)等を付加することも
できる(const auto&, auto*, etc...)




                   わんくま同盟 東京勉強会 #22
decltype

• 計算結果の型を求めることができる
• 他の機能で型を推論に使われたり、インスタンスか
  らメンバの型を取得したり…

int x = 3;
decltype(x) y = 0;   // int y = 0;
decltype(x*) z = &x; // int* z = &x;


int foo() { return 0; }
decltype(foo()) x = foo(); // int x = foo();



                   わんくま同盟 東京勉強会 #22
Delegating Constructor

• 移譲コンストラクタ
• コンストラクタ内で、他のコンストラクタを呼べる

class widget {
  int x_, y_, z_;

  widget(int x, int y, int z)
    : x_(x), y_(y), z_(z) {}
public:
  widget()
    : widget(0, 0, 0) {} // widget(int, int, int)
};

                    わんくま同盟 東京勉強会 #22
Extending sizeof(拡張sizeof)

• インスタンス作成せずにメンバ変数を sizeof できる
  ようになる

struct hoge {
  int id;
};

sizeof(hoge::id); // 今まではできなかった




                     わんくま同盟 東京勉強会 #22
Raw String Literal

• Rプレフィックスを付加した文字列は
  エスケープシーケンスを無視するようになる

// C++03
string path = “C:¥¥abc”;
string data = “Akira¥¥nTakahashi”;
wstring wpath = L”C:¥¥abc”;

// C++0x
string path = R”C:¥abc”;
string data = R”Akira¥nTakahashi”;
wstring wpath = LR”C:¥abc”;

                 わんくま同盟 東京勉強会 #22
Defaulted and Deleted Functions

• コンパイラによって自動生成される関数の制御が
 できるようになる

struct hoge {
    hoge() = default;
      // コンパイラが自動生成するデフォルトコンストラクタを使う

     // コピー禁止
     hoge(const hoge&) = delete;
     hoge& operator=(const hoge&) = delete;
};



                    わんくま同盟 東京勉強会 #22
Member Initializers(メンバ初期化子)

• メンバ変数の宣言時に初期化できるようになる

struct hoge {
  int    age = 23;
  string name(“Akira”);
};


• コンストラクタでの初期化子リストが優先される




                   わんくま同盟 東京勉強会 #22
nullptr

• ヌルポインタを表すキーワード nullptr を追加
• nullptrが導入されれば、0とNULLを非推奨とするこ
  とができる

int* p = nullptr;              // C++0x
int* p = static_cast<int*>(0); // C++03
int* p = NULL;                 // C...(void*)0




                   わんくま同盟 東京勉強会 #22
constexpr

• 定数式
• コンパイル時に実行される式を作成することができる


constexpr int size(int x) {
  return x * 2;
}

int ar[size(3)]; // OK...配列のサイズは6

いろいろと制限があるらしい(再帰ができない等...)

                  わんくま同盟 東京勉強会 #22
Template Aliases

• テンプレートを使用して型の別名を付けることができ
  るようになる(いわゆる template typedef)

template <class T>
using Vec = vector<T>;

Vec<int> v;



• 型を返すメタ関数が書きやすくなる
 (もしくはいらなくなる)

                   わんくま同盟 東京勉強会 #22
static_assert

• コンパイル時アサート
• 静的な条件と、エラーメッセージを指定する

template <class T>
void foo(T value) {
  static_assert(is_integral<T>::value,
                “not integral”);
}

foo(3);    // OK
foo(3.14); // エラー! not integral



                   わんくま同盟 東京勉強会 #22
Variadic Templates
• 可変引数テンプレート
• 基本的に再帰を使って処理する

template <class T>
void print(T arg) {
  cout << arg << endl;
}

template <class Head, class... Tail>
void print(Head head, Tail... tail) {
  cout << head << endl;
  print(tail...);
}

print(1, 2, 3, 4, 5, 6, 7);


ちなみに、sizeof...(Args); とすると、型の数を取得できる

                         わんくま同盟 東京勉強会 #22
Concept

• 型に対する制約
• テンプレートをより簡単にし、より強力にするもの

コンセプトには以下の3つの機能がある
• Concept definitions
• Requirements clauses
• Concept maps




          わんくま同盟 東京勉強会 #22
Concept definitions

• 型に対する要求を定義する
  「型Tはxxメンバを持っていなければならない」
  「型Tはyy型を持っていなければならない」


concept LessThanComparable<class T> {
  bool operator<(const T&, const T&);
}

このコンセプトは、「型Tは operator< を持っていなければならない」
という要求




                   わんくま同盟 東京勉強会 #22
Requirements clauses

• 型Tに必要な要求(コンセプト)を指定する

template <class T>
requires LessThanComparable<T>
const T& min(const T& a, const T& b) {
  return a < b ? a : b;
}
これにより
「型TはLessThanComparableの要求を満たさなければならない」
といった制約を行うことができる




               わんくま同盟 東京勉強会 #22
ここまででうれしいこと

• 人間が読めるコンパイルエラーを出力してくれる

list<int> ls;
sort(ls.begin(), ls.end()); // エラー!

「第1引数はRandomAccessIteratorの要求を満たしません」
といったエラーメッセージを出力してくれるだろう




                     わんくま同盟 東京勉強会 #22
Concept maps その1

• 既存の型がどのようにコンセプトの要求を満たすか
  を定義する

以下のようなコンセプトとそれを要求する関数があった場合
concept RandomAccessIterator<class T> {
  typename value_type;
  typename difference_type;
}

template <RandomAccessIterator Iterator>
void sort(Iterator first, Iterator last) {
  ...
}

                    わんくま同盟 東京勉強会 #22
Concept maps その2

以下のような結果になる

vector<int> v;
sort(v.begin(), v.end()); // OK

int ar[] = {3, 1, 4};
sort(ar, ar + 3);
    // エラー!ポインタはRandomAccessIteratorの要求を満たしません

ポインタはランダムアクセスイテレータとして使用できなければならない




                   わんくま同盟 東京勉強会 #22
Concept maps その3

• そこで、concept_mapを使用して
  RandomAccessIteratorコンセプトを特殊化する

template <class T>
concept_map RandomAccessIterator<T*> {
  typedef T         value_type;
  typedef ptrdiff_t difference_type;
}

これにより、ポインタをRandomAccessIteratorとして使える




                   わんくま同盟 東京勉強会 #22
Concept mapsがあるとできること

• Containerコンセプトを使用することにより
  配列をコンテナとして使用することができる

template <Container Cont>
void sort(Cont& c) {
  sort(c.begin(), c.end());
}

std::vector<int> v;
sort(v); // OK

int ar[] = {3, 1, 4};
sort(ar); // OK


                 わんくま同盟 東京勉強会 #22
書ききれないコンセプト

•   Range-baseのアルゴリズムは(まだ?)提供されない
•   requiresはカンマ区切りで複数指定可能
•   late_checkブロックで従来の型チェックも可能
•   コンセプトでのオーバーロードも可能
•   Scoped Concept Mapsとか・・・
•   Axiomとか・・・

• コンセプトは超強力!!!




              わんくま同盟 東京勉強会 #22
Range-base for loop

• コレクションを走査するfor文
• std::Rangeコンセプトを使用している

vector<int> v;
for (const int& item : v) {
  cout << item << endl;
}

初期化子リストを渡すことも可能
for (int item : {3, 1, 4}) {
    ...
}

                   わんくま同盟 東京勉強会 #22
右辺値参照・Move Semantics

• 右辺値(一時オブジェクト)はどうせ消えちゃうのだから
  内部のメモリを移動しても問題ないでしょ。というもの
• 移動された一時オブジェクトは破壊される
• 右辺値参照には&&演算子を使用する


template <class T>
class vector {
public:
  vector(const vector&); // Copy Constructor
  vector(vector&&);      // Move Constructor
};



                   わんくま同盟 東京勉強会 #22
左辺値と右辺値

• 左辺値とは
 ・名前が付いたオブジェクトを指す

• 右辺値とは
 ・名前がないオブジェクトを指す
 ・関数の戻り値は、参照やポインタでない限り
  右辺値(一時オブジェクト)である




         わんくま同盟 東京勉強会 #22
右辺値参照を使ってみる

右辺値参照は、使う側はとくに気にする必要がない(ことが多い)


vector<int> factory()
{
  vector<int> v;
  ...
  return v;
}

vector<int> v = factory(); // Move Contructor

右辺値参照を使えば大きいオブジェクトを気軽に戻り値にできる


                   わんくま同盟 東京勉強会 #22
右辺値参照のための標準関数
•   <utility>にstd::moveとstd::forwardという2つの関数が用意される
namespace std {
  template <class T>
  struct identity {
    typedef T type;
  };

    template <class T>
    inline typename remove_reference<T>::type&& move(T&& x)
      { return x; }

    template <class T>
    inline T&& forward(typename identity<T>::type&& x)
      { return x; }
}

・std::move は左辺値を右辺値に変換する関数
・std::forward は右辺値を安全に転送する関数


                         わんくま同盟 東京勉強会 #22
基本的な
       Move ConstructorとMove Assinmentの書き方
class Derived : public Base {
    std::vector<int> vec;
    std::string      name;
public:
    // move constructor
    Derived(Derived&& x)
        : Base(std::forward<Base>(x)),
          vec(std::move(x.vec)),
          name(std::move(x.name)){}

     // move assignment operator
     Derived& operator=(Derived&& x) {
         Base::operator=(std::forward<Base>(x));
         vec = std::move(x.vec);
         name = std::move(x.name);
         return *this;
     }
};

                      わんくま同盟 東京勉強会 #22
Lambda Expression(ラムダ式)

• 匿名関数オブジェクト

vector<int> v;
find_if(v.begin(), v.end(),
            [](int x) { return x == 3; });

以下はラムダ式によって生成される匿名関数オブジェクト(簡易的)
struct F {
  bool operator()(int x) {
    return x == 3;
  }
};


                   わんくま同盟 東京勉強会 #22
環境のキャプチャ

• デフォルトのキャプチャ方法
vector<int> v;
int sum = 0;
int rate = 2;
for_each(v.begin(), v.end(), [&](int x) { sum += x * rate; });

[&] : デフォルトのキャプチャ方法は参照
[=] : デフォルトのキャプチャ方法はコピー
[] : 環境なし

• キャプチャリスト(個別指定)
for_each(v.begin(), v.end(), [=, &sum] { sum += x * rate; });

デフォルトのキャプチャ方法はコピー、sumは参照でキャプチャ




                       わんくま同盟 東京勉強会 #22
戻り値の型

• ラムダ式の戻り値の型は明示的に指定することもできる
[](int x) -> bool { return x == 3; }



• 省略した場合は、return文をdecltypeした型が戻り値の型
以下の2つのラムダ式は同じ意味である
[](int x) -> decltype(x == 3) { return x == 3; }
[](int x)                     { return x == 3; }

return 文を省略した場合、戻り値の型は void になる




                   わんくま同盟 東京勉強会 #22
書ききれなかったラムダ
•   メンバ関数内でのラムダ式はそのクラスのfriendと見なされ、
    privateメンバにアクセスできる

•   参照環境のみを持つラムダ式はstd::reference_closureを継承したクラスになる
    (キャプチャした変数をメンバに持たずにスコープをのぞき見る)

•   参照環境のみを持つラムダ式はスコープから外れるとその実行は未定義
    (つまり、参照ラムダを戻り値にしてはいけない)

•   const/volatile修飾も可能... []() const {}

•   例外指定も可能... []() throw {}




                            わんくま同盟 東京勉強会 #22
新たな関数宣言構文(戻り値の型を後置)
• 現在
  vector<double> foo();

• 提案1:戻り値の型を後置する関数宣言構文
  auto foo() -> vector<double>;

• 提案2:(ラムダ式と)統一された関数宣言構文
  []foo() -> vector<double>;

戻り値の型を後置できると、引数をdecltypeした型を戻り値の型
にすることができる
ラムダ式と同様に戻り値の型を推論することも検討中

               わんくま同盟 東京勉強会 #22
書ききれなかった言語仕様

•   char16_t/char32_t
•   Alignment
•   union の制限解除
•   Strongly Typed Enums
•   explicit conversion
•   継承コンストラクタ
•   ユーザー定義リテラル
•   60進数リテラル(?)
•   Nested Exception
•   Uniformed initialization
•   etc...

                       わんくま同盟 東京勉強会 #22
まとめ

• C++0x には、プログラミングをより簡単にするため
  の拡張が数多くあります

• 紹介しきれませんでしたが、標準ライブラリもかなり
  強力になっています

• C++0x で遊ぼう!!




           わんくま同盟 東京勉強会 #22
参考サイト
•   C++ Standards Committee Papers
http://www.open-std.org/jtc1/sc22/wg21/docs/papers/

•   Wikipedia(英語)
http://en.wikipedia.org/wiki/C%2B%2B0x

•   Faith and Brave – C++で遊ぼう
http://d.hatena.ne.jp/faith_and_brave/

•   Cry’s Diary
http://d.hatena.ne.jp/Cryolite/


•   ntnekの日記
http://d.hatena.ne.jp/ntnek/


•   かそくそうち
http://d.hatena.ne.jp/y-hamigaki/



                                     わんくま同盟 東京勉強会 #22

More Related Content

PDF
クロージャデザインパターン
PDF
Emcpp item31
PDF
C++ Template Meta Programming の紹介@社内勉強会
PPTX
競技プログラミングのためのC++入門
PDF
templateとautoの型推論
PDF
C++0x in programming competition
PDF
ゲーム開発者のための C++11/C++14
PDF
Pfi Seminar 2010 1 7
クロージャデザインパターン
Emcpp item31
C++ Template Meta Programming の紹介@社内勉強会
競技プログラミングのためのC++入門
templateとautoの型推論
C++0x in programming competition
ゲーム開発者のための C++11/C++14
Pfi Seminar 2010 1 7

What's hot (20)

PDF
C++ ポインタ ブートキャンプ
PPTX
PDF
すごいConstたのしく使おう!
PDF
Emcjp item21
PDF
Replace Output Iterator and Extend Range JP
PPTX
Effective modern C++ 勉強会 #3 Item 12
PDF
今から始める Lens/Prism
PDF
わんくま同盟大阪勉強会#61
PDF
C++コミュニティーの中心でC++をDISる
PDF
What is template
PPTX
最新C++事情 C++14-C++20 (2018年10月)
PDF
オブジェクト指向できていますか?
PDF
C++11概要 ライブラリ編
PPTX
C# 8.0 null許容参照型
PDF
競技プログラミングにおけるコードの書き方とその利便性
PDF
Effective Modern C++ 勉強会#1 Item3,4
PDF
error handling using expected
PPTX
C#6.0の新機能紹介
KEY
Clojure programming-chapter-2
KEY
Objc lambda
C++ ポインタ ブートキャンプ
すごいConstたのしく使おう!
Emcjp item21
Replace Output Iterator and Extend Range JP
Effective modern C++ 勉強会 #3 Item 12
今から始める Lens/Prism
わんくま同盟大阪勉強会#61
C++コミュニティーの中心でC++をDISる
What is template
最新C++事情 C++14-C++20 (2018年10月)
オブジェクト指向できていますか?
C++11概要 ライブラリ編
C# 8.0 null許容参照型
競技プログラミングにおけるコードの書き方とその利便性
Effective Modern C++ 勉強会#1 Item3,4
error handling using expected
C#6.0の新機能紹介
Clojure programming-chapter-2
Objc lambda
Ad

Similar to C++0x 言語の未来を語る (20)

PDF
C++0x concept
PDF
C++0xの概要(デブサミ2010)
PDF
Boost tour 1_40_0
PPTX
T69 c++cli ネイティブライブラリラッピング入門
PDF
boost tour 1.48.0 all
PPTX
ぱっと見でわかるC++11
ODP
これから Haskell を書くにあたって
PDF
C++14 Overview
PDF
C++ template-primer
PPTX
T93 com入門
PDF
Move semantics
PPTX
boost - std - C#
PPTX
Visual C++で使えるC++11
PDF
Boost.Flyweight
PDF
リテラル文字列型までの道
PDF
中3女子でもわかる constexpr
PDF
Boost Tour 1.50.0 All
PPTX
C++ tips4 cv修飾編
PDF
C++ lecture-0
C++0x concept
C++0xの概要(デブサミ2010)
Boost tour 1_40_0
T69 c++cli ネイティブライブラリラッピング入門
boost tour 1.48.0 all
ぱっと見でわかるC++11
これから Haskell を書くにあたって
C++14 Overview
C++ template-primer
T93 com入門
Move semantics
boost - std - C#
Visual C++で使えるC++11
Boost.Flyweight
リテラル文字列型までの道
中3女子でもわかる constexpr
Boost Tour 1.50.0 All
C++ tips4 cv修飾編
C++ lecture-0
Ad

More from Akira Takahashi (20)

PPTX
Cpp20 overview language features
PDF
Cppmix 02
PPTX
Cppmix 01
PDF
Modern C++ Learning
PDF
cpprefjp documentation
PDF
C++1z draft
PDF
Boost tour 1_61_0 merge
PDF
Boost tour 1_61_0
PDF
Boost tour 1.60.0 merge
PDF
Boost tour 1.60.0
PDF
Boost container feature
PDF
Boost Tour 1_58_0 merge
PDF
Boost Tour 1_58_0
PDF
C++14 solve explicit_default_constructor
PDF
C++14 enum hash
PDF
Multi paradigm design
PDF
Start Concurrent
PDF
Programmer mind
PDF
Boost.Study 14 Opening
PDF
Executors and schedulers
Cpp20 overview language features
Cppmix 02
Cppmix 01
Modern C++ Learning
cpprefjp documentation
C++1z draft
Boost tour 1_61_0 merge
Boost tour 1_61_0
Boost tour 1.60.0 merge
Boost tour 1.60.0
Boost container feature
Boost Tour 1_58_0 merge
Boost Tour 1_58_0
C++14 solve explicit_default_constructor
C++14 enum hash
Multi paradigm design
Start Concurrent
Programmer mind
Boost.Study 14 Opening
Executors and schedulers

C++0x 言語の未来を語る

  • 1. C++0x 言語の未来を語る 高橋 晶(アキラ) Blog: Faith and Brave – C++で遊ぼう わんくま同盟 東京勉強会 #22
  • 2. Agenda • What’s C++0x • Angle Bracket • Initializer List • auto • decltype • Delegating Constructor • Extending sizeof • Raw String Literal • Defaulted and Deleted Functions • Member Initializers • nullptr • constexpr • Template Aliases • static_assert • Variadic Templates • Concept • Range-base for loop • RValue Reference・Move Semantics • Lambda Expression • New Function Daclarator Syntax わんくま同盟 東京勉強会 #22
  • 3. What’s C++0x (C++0xってなに?) • C++の次バージョン(現在はC++03) • 「0x」とは200x年の意味で、C++09を目指している (もしかしたら C++10 になっちゃうかも) • エキスパートよりも初心者のための言語拡張を行う わんくま同盟 東京勉強会 #22
  • 4. Angle Bracket(山カッコ) • C++03では以下のコードはコンパイルエラーになる vector<basic_string<char>> v; // エラー! operator>> が使われている • 連続した山カッコがシフト演算子と判断されてしまう • C++0xではこの問題が解決される わんくま同盟 東京勉強会 #22
  • 5. Initializer List(初期化子リスト) • ユーザー定義クラスで配列のような初期化を可能にする • Bjarne氏曰く「何で今までできなかったのかわからない」 • std::initializer_listクラスを使用する // 初期化 vector<int> v = {3, 1, 4}; // 戻り値 vector<int> factory() { return {3, 1, 4}; } // 引数 void foo(const vector<int>& v) {} foo({3, 1, 4}); わんくま同盟 東京勉強会 #22
  • 6. auto • 型推論 • autoキーワードの意味が変更になる(めずらしい) • autoで宣言された変数の型は右辺から導出される vector<int> v; vector<int>::iterator it = v.begin(); // C++03 auto it = v.begin(); // C++0x const/volatile修飾や、参照(&)・ポインタ(*)等を付加することも できる(const auto&, auto*, etc...) わんくま同盟 東京勉強会 #22
  • 7. decltype • 計算結果の型を求めることができる • 他の機能で型を推論に使われたり、インスタンスか らメンバの型を取得したり… int x = 3; decltype(x) y = 0; // int y = 0; decltype(x*) z = &x; // int* z = &x; int foo() { return 0; } decltype(foo()) x = foo(); // int x = foo(); わんくま同盟 東京勉強会 #22
  • 8. Delegating Constructor • 移譲コンストラクタ • コンストラクタ内で、他のコンストラクタを呼べる class widget { int x_, y_, z_; widget(int x, int y, int z) : x_(x), y_(y), z_(z) {} public: widget() : widget(0, 0, 0) {} // widget(int, int, int) }; わんくま同盟 東京勉強会 #22
  • 9. Extending sizeof(拡張sizeof) • インスタンス作成せずにメンバ変数を sizeof できる ようになる struct hoge { int id; }; sizeof(hoge::id); // 今まではできなかった わんくま同盟 東京勉強会 #22
  • 10. Raw String Literal • Rプレフィックスを付加した文字列は エスケープシーケンスを無視するようになる // C++03 string path = “C:¥¥abc”; string data = “Akira¥¥nTakahashi”; wstring wpath = L”C:¥¥abc”; // C++0x string path = R”C:¥abc”; string data = R”Akira¥nTakahashi”; wstring wpath = LR”C:¥abc”; わんくま同盟 東京勉強会 #22
  • 11. Defaulted and Deleted Functions • コンパイラによって自動生成される関数の制御が できるようになる struct hoge { hoge() = default; // コンパイラが自動生成するデフォルトコンストラクタを使う // コピー禁止 hoge(const hoge&) = delete; hoge& operator=(const hoge&) = delete; }; わんくま同盟 東京勉強会 #22
  • 12. Member Initializers(メンバ初期化子) • メンバ変数の宣言時に初期化できるようになる struct hoge { int age = 23; string name(“Akira”); }; • コンストラクタでの初期化子リストが優先される わんくま同盟 東京勉強会 #22
  • 13. nullptr • ヌルポインタを表すキーワード nullptr を追加 • nullptrが導入されれば、0とNULLを非推奨とするこ とができる int* p = nullptr; // C++0x int* p = static_cast<int*>(0); // C++03 int* p = NULL; // C...(void*)0 わんくま同盟 東京勉強会 #22
  • 14. constexpr • 定数式 • コンパイル時に実行される式を作成することができる constexpr int size(int x) { return x * 2; } int ar[size(3)]; // OK...配列のサイズは6 いろいろと制限があるらしい(再帰ができない等...) わんくま同盟 東京勉強会 #22
  • 15. Template Aliases • テンプレートを使用して型の別名を付けることができ るようになる(いわゆる template typedef) template <class T> using Vec = vector<T>; Vec<int> v; • 型を返すメタ関数が書きやすくなる (もしくはいらなくなる) わんくま同盟 東京勉強会 #22
  • 16. static_assert • コンパイル時アサート • 静的な条件と、エラーメッセージを指定する template <class T> void foo(T value) { static_assert(is_integral<T>::value, “not integral”); } foo(3); // OK foo(3.14); // エラー! not integral わんくま同盟 東京勉強会 #22
  • 17. Variadic Templates • 可変引数テンプレート • 基本的に再帰を使って処理する template <class T> void print(T arg) { cout << arg << endl; } template <class Head, class... Tail> void print(Head head, Tail... tail) { cout << head << endl; print(tail...); } print(1, 2, 3, 4, 5, 6, 7); ちなみに、sizeof...(Args); とすると、型の数を取得できる わんくま同盟 東京勉強会 #22
  • 19. Concept definitions • 型に対する要求を定義する 「型Tはxxメンバを持っていなければならない」 「型Tはyy型を持っていなければならない」 concept LessThanComparable<class T> { bool operator<(const T&, const T&); } このコンセプトは、「型Tは operator< を持っていなければならない」 という要求 わんくま同盟 東京勉強会 #22
  • 20. Requirements clauses • 型Tに必要な要求(コンセプト)を指定する template <class T> requires LessThanComparable<T> const T& min(const T& a, const T& b) { return a < b ? a : b; } これにより 「型TはLessThanComparableの要求を満たさなければならない」 といった制約を行うことができる わんくま同盟 東京勉強会 #22
  • 21. ここまででうれしいこと • 人間が読めるコンパイルエラーを出力してくれる list<int> ls; sort(ls.begin(), ls.end()); // エラー! 「第1引数はRandomAccessIteratorの要求を満たしません」 といったエラーメッセージを出力してくれるだろう わんくま同盟 東京勉強会 #22
  • 22. Concept maps その1 • 既存の型がどのようにコンセプトの要求を満たすか を定義する 以下のようなコンセプトとそれを要求する関数があった場合 concept RandomAccessIterator<class T> { typename value_type; typename difference_type; } template <RandomAccessIterator Iterator> void sort(Iterator first, Iterator last) { ... } わんくま同盟 東京勉強会 #22
  • 23. Concept maps その2 以下のような結果になる vector<int> v; sort(v.begin(), v.end()); // OK int ar[] = {3, 1, 4}; sort(ar, ar + 3); // エラー!ポインタはRandomAccessIteratorの要求を満たしません ポインタはランダムアクセスイテレータとして使用できなければならない わんくま同盟 東京勉強会 #22
  • 24. Concept maps その3 • そこで、concept_mapを使用して RandomAccessIteratorコンセプトを特殊化する template <class T> concept_map RandomAccessIterator<T*> { typedef T value_type; typedef ptrdiff_t difference_type; } これにより、ポインタをRandomAccessIteratorとして使える わんくま同盟 東京勉強会 #22
  • 25. Concept mapsがあるとできること • Containerコンセプトを使用することにより 配列をコンテナとして使用することができる template <Container Cont> void sort(Cont& c) { sort(c.begin(), c.end()); } std::vector<int> v; sort(v); // OK int ar[] = {3, 1, 4}; sort(ar); // OK わんくま同盟 東京勉強会 #22
  • 26. 書ききれないコンセプト • Range-baseのアルゴリズムは(まだ?)提供されない • requiresはカンマ区切りで複数指定可能 • late_checkブロックで従来の型チェックも可能 • コンセプトでのオーバーロードも可能 • Scoped Concept Mapsとか・・・ • Axiomとか・・・ • コンセプトは超強力!!! わんくま同盟 東京勉強会 #22
  • 27. Range-base for loop • コレクションを走査するfor文 • std::Rangeコンセプトを使用している vector<int> v; for (const int& item : v) { cout << item << endl; } 初期化子リストを渡すことも可能 for (int item : {3, 1, 4}) { ... } わんくま同盟 東京勉強会 #22
  • 28. 右辺値参照・Move Semantics • 右辺値(一時オブジェクト)はどうせ消えちゃうのだから 内部のメモリを移動しても問題ないでしょ。というもの • 移動された一時オブジェクトは破壊される • 右辺値参照には&&演算子を使用する template <class T> class vector { public: vector(const vector&); // Copy Constructor vector(vector&&); // Move Constructor }; わんくま同盟 東京勉強会 #22
  • 29. 左辺値と右辺値 • 左辺値とは ・名前が付いたオブジェクトを指す • 右辺値とは ・名前がないオブジェクトを指す ・関数の戻り値は、参照やポインタでない限り 右辺値(一時オブジェクト)である わんくま同盟 東京勉強会 #22
  • 30. 右辺値参照を使ってみる 右辺値参照は、使う側はとくに気にする必要がない(ことが多い) vector<int> factory() { vector<int> v; ... return v; } vector<int> v = factory(); // Move Contructor 右辺値参照を使えば大きいオブジェクトを気軽に戻り値にできる わんくま同盟 東京勉強会 #22
  • 31. 右辺値参照のための標準関数 • <utility>にstd::moveとstd::forwardという2つの関数が用意される namespace std { template <class T> struct identity { typedef T type; }; template <class T> inline typename remove_reference<T>::type&& move(T&& x) { return x; } template <class T> inline T&& forward(typename identity<T>::type&& x) { return x; } } ・std::move は左辺値を右辺値に変換する関数 ・std::forward は右辺値を安全に転送する関数 わんくま同盟 東京勉強会 #22
  • 32. 基本的な Move ConstructorとMove Assinmentの書き方 class Derived : public Base { std::vector<int> vec; std::string name; public: // move constructor Derived(Derived&& x) : Base(std::forward<Base>(x)), vec(std::move(x.vec)), name(std::move(x.name)){} // move assignment operator Derived& operator=(Derived&& x) { Base::operator=(std::forward<Base>(x)); vec = std::move(x.vec); name = std::move(x.name); return *this; } }; わんくま同盟 東京勉強会 #22
  • 33. Lambda Expression(ラムダ式) • 匿名関数オブジェクト vector<int> v; find_if(v.begin(), v.end(), [](int x) { return x == 3; }); 以下はラムダ式によって生成される匿名関数オブジェクト(簡易的) struct F { bool operator()(int x) { return x == 3; } }; わんくま同盟 東京勉強会 #22
  • 34. 環境のキャプチャ • デフォルトのキャプチャ方法 vector<int> v; int sum = 0; int rate = 2; for_each(v.begin(), v.end(), [&](int x) { sum += x * rate; }); [&] : デフォルトのキャプチャ方法は参照 [=] : デフォルトのキャプチャ方法はコピー [] : 環境なし • キャプチャリスト(個別指定) for_each(v.begin(), v.end(), [=, &sum] { sum += x * rate; }); デフォルトのキャプチャ方法はコピー、sumは参照でキャプチャ わんくま同盟 東京勉強会 #22
  • 35. 戻り値の型 • ラムダ式の戻り値の型は明示的に指定することもできる [](int x) -> bool { return x == 3; } • 省略した場合は、return文をdecltypeした型が戻り値の型 以下の2つのラムダ式は同じ意味である [](int x) -> decltype(x == 3) { return x == 3; } [](int x) { return x == 3; } return 文を省略した場合、戻り値の型は void になる わんくま同盟 東京勉強会 #22
  • 36. 書ききれなかったラムダ • メンバ関数内でのラムダ式はそのクラスのfriendと見なされ、 privateメンバにアクセスできる • 参照環境のみを持つラムダ式はstd::reference_closureを継承したクラスになる (キャプチャした変数をメンバに持たずにスコープをのぞき見る) • 参照環境のみを持つラムダ式はスコープから外れるとその実行は未定義 (つまり、参照ラムダを戻り値にしてはいけない) • const/volatile修飾も可能... []() const {} • 例外指定も可能... []() throw {} わんくま同盟 東京勉強会 #22
  • 37. 新たな関数宣言構文(戻り値の型を後置) • 現在 vector<double> foo(); • 提案1:戻り値の型を後置する関数宣言構文 auto foo() -> vector<double>; • 提案2:(ラムダ式と)統一された関数宣言構文 []foo() -> vector<double>; 戻り値の型を後置できると、引数をdecltypeした型を戻り値の型 にすることができる ラムダ式と同様に戻り値の型を推論することも検討中 わんくま同盟 東京勉強会 #22
  • 38. 書ききれなかった言語仕様 • char16_t/char32_t • Alignment • union の制限解除 • Strongly Typed Enums • explicit conversion • 継承コンストラクタ • ユーザー定義リテラル • 60進数リテラル(?) • Nested Exception • Uniformed initialization • etc... わんくま同盟 東京勉強会 #22
  • 39. まとめ • C++0x には、プログラミングをより簡単にするため の拡張が数多くあります • 紹介しきれませんでしたが、標準ライブラリもかなり 強力になっています • C++0x で遊ぼう!! わんくま同盟 東京勉強会 #22
  • 40. 参考サイト • C++ Standards Committee Papers http://www.open-std.org/jtc1/sc22/wg21/docs/papers/ • Wikipedia(英語) http://en.wikipedia.org/wiki/C%2B%2B0x • Faith and Brave – C++で遊ぼう http://d.hatena.ne.jp/faith_and_brave/ • Cry’s Diary http://d.hatena.ne.jp/Cryolite/ • ntnekの日記 http://d.hatena.ne.jp/ntnek/ • かそくそうち http://d.hatena.ne.jp/y-hamigaki/ わんくま同盟 東京勉強会 #22