読者です 読者をやめる 読者になる 読者になる

C++0x ライブラリ - TR1(Technical Report 1)

C++

主にBoost C++ Librariesから移植(?)される新規標準ライブラリ


ネームスペースはstd
(std::tr1はなくなったみたいですね)



今回はとりあえずBoostから移植されるもののみ紹介
(残りはC99互換ライブラリ、数学関数 etc...)




【スマートポインタ(shared_ptr, weak_ptr)】

shared_ptr(参照カウント付きスマートポインタ)
weak_ptr(shared_ptrの循環参照を防ぐためのスマートポインタ)

#include <memory>

using namespace std;

void foo(shared_ptr<widget> p)
{
    ...
} // not delete p

int main()
{
    shared_ptr<widget> p(new widget);

    foo(p);

    return 0; // delete p;
}

shared_array(shared_ptrの配列版)はTR1には含まれないので
vector>を使いましょう




【固定長配列(array)】

配列のクラス版
要素数の取得や、begin(), end()等でイテレータ取得もできる

#include <array>

using namespace std;

int main()
{
    array<int, 3> ar = {3, 1, 4};

    // 添字での参照
    ar[1] = 2; // 3, 2, 4

    // イテレータ処理
    sort(ar.begin(), ar.end());

    // 要素数の取得が可能
    for (int index = 0; index < ar.size(); ++index)
        ...

    // 拡張for文に適用可
    for (int value : ar)
        ...

    return 0;
}

【タプル型(tuple)】

簡易構造体のようなもの
複数の型の複数の値を保持できる

#include <tuple>
#include <string>

using namespace std;

tuple<int, string, double> get_info()
{
    return make_tuple(3, "abc", 3.14);
}

int main()
{
    tuple<int, string, double> tup = get_info();

    int    value = get<0>(tup);
    string str   = get<1>(tup);
    double pi    = get<2>(tup);

    return 0;
}

【型特性(type_traits)】

型に関する情報を取得する

#include <type_traits>

using namespace std;

template <class T>
void foo(const T& value)
{
    // 型Tが整数型(int, long, short, bool, char...)でなければコンパイルエラーにする
    static_assert(is_integral<T>::value, "not integral");
}

int main()
{
    foo(3);     // int......OK
    foo(false); // bool.....OK
    foo('a');   // char.....OK
    foo(3.14);  // double...エラー

    return 0;
}


一覧はこんな感じ...enable_ifはあるのにdisable_ifないのか…

// [20.4.3] helper class:
template <class T, T v> struct integral_constant;
typedef integral_constant<bool, true> true_type;
typedef integral_constant<bool, false> false_type;

// [20.4.4.1] primary type categories:
template <class T> struct is_void;
template <class T> struct is_integral;
template <class T> struct is_floating_point;
template <class T> struct is_array;
template <class T> struct is_pointer;
template <class T> struct is_lvalue_reference;
template <class T> struct is_rvalue_reference;
template <class T> struct is_member_object_pointer;
template <class T> struct is_member_function_pointer;
template <class T> struct is_enum;
template <class T> struct is_union;
template <class T> struct is_class;
template <class T> struct is_function;

// [20.4.4.2] composite type categories:
template <class T> struct is_reference;
template <class T> struct is_arithmetic;
template <class T> struct is_fundamental;
template <class T> struct is_object;
template <class T> struct is_scalar;
template <class T> struct is_compound;
template <class T> struct is_member_pointer;

// [20.4.4.3] type properties:
template <class T> struct is_const;
template <class T> struct is_volatile;
template <class T> struct is_trivial;
template <class T> struct is_standard_layout;
template <class T> struct is_pod;
template <class T> struct is_empty;
template <class T> struct is_polymorphic;
template <class T> struct is_abstract;
template <class T> struct has_trivial_default_constructor;
template <class T> struct has_trivial_copy_constructor;
template <class T> struct has_trivial_assign;
template <class T> struct has_trivial_destructor;
template <class T> struct has_nothrow_default_constructor;
template <class T> struct has_nothrow_copy_constructor;
template <class T> struct has_nothrow_assign;
template <class T> struct has_virtual_destructor;
template <class T> struct is_signed;
template <class T> struct is_unsigned;
template <class T> struct alignment_of;
template <class T> struct rank;
template <class T, unsigned I = 0> struct extent;

// [20.4.5] type relations:
template <class T, class U> struct is_same;
template <class Base, class Derived> struct is_base_of;
template <class From, class To> struct is_convertible;

// [20.4.6.1] const-volatile modifications:
template <class T> struct remove_const;
template <class T> struct remove_volatile;
template <class T> struct remove_cv;
template <class T> struct add_const;
template <class T> struct add_volatile;
template <class T> struct add_cv;

// [20.4.6.2] reference modifications:
template <class T> struct remove_reference;
template <class T> struct add_lvalue_reference;
template <class T> struct add_rvalue_reference;

// [20.4.6.3] sign modifications:
template <class T> struct make_signed;
template <class T> struct make_unsigned;

// [20.4.6.4] array modifications:
template <class T> struct remove_extent;
template <class T> struct remove_all_extents;

// [20.4.6.5] pointer modifications:
template <class T> struct remove_pointer;
template <class T> struct add_pointer;

// [20.4.7] other transformations:
template <std::size_t Len, std::size_t Align> struct aligned_storage;
template <std::size_t Len, class... Types> struct aligned_union;
template <class T> struct decay;
template <bool, class T = void> struct enable_if;
template <bool, class T, class F> struct conditional;


【参照ラッパ(ref, cref)】

引数をコピーではなく参照で渡す

#include <iostream>
#include <functional>

using namespace std;

void add(int& value)
{
    ++value;
}

template <class Pred, class Param>
void foo(Pred pred, Param param)
{
    pred(param);
}

int main()
{
    int value = 0;

    foo(add, value);
    cout << value << endl; // 0

    foo(add, ref(value));
    cout << value << endl; // 1

    return 0;
}

【束縛子(bind)】

#include <iostream>
#include <vector>
#include <functional>

using namespace std;

void disp(int no1, int no2, int no3)
{
    cout << no1 << no2, << no3 << endl;
}

int main()
{
    vector<int> v = {3, 1, 4};

    for_each(v, bind(disp, 0, _1, 9));
        // 0, 3, 9
        // 0, 1, 9
        // 0, 4, 9

    return 0;
}

【関数の戻り値の型(result_of)】

関数適用結果の戻り値の型を取得する

#include <iostream>
#include <functional>

using namespace std;

// 関数
typedef int(*func)(double, double);

// result_ofで関数の戻り値の型を取得
typedef result_of<func(double, double)>::type result_type;

int main()
{
    cout << typeid(result_type).name() << endl; // int

    return 0;
}

【メンバ関数アダプタ(mem_fn)】

std::mem_fun, std::mem_fun_refの汎用版

メンバ関数を関数のように使う

#include <iostream>
#include <vector>
#include <string>
#include <algorithm> // for_each
#include <functional>

using namespace std;

class person {
    string name_;
public:
    person(const string& name)
        : name_(name) {}

    void disp() const
    {
        cout << name_ << endl;
    }
};

int main()
{
    vector<person> v;

    v.push_back(person("Akira"));
    v.push_back(person("Johnny"));
    v.push_back(person("Millia"));

    for_each(v, mem_fn(&person::disp)); // mem_fun_refの代わり

    // ↑の内部的な動作
    for (const person& per : v)
        per.disp();


    vector<person*> vp;

    vp.push_back(new person("Akira"));
    vp.push_back(new person("Johnny"));
    vp.push_back(new person("Millia"));

    for_each(vp, mem_fn(&person::disp)); // mem_funの代わり

    // ↑の内部的な動作
    for (const person *per : vp)
        per->disp();


    for (person *per : vp)
        delete per;

    return 0;
}

【汎用関数オブジェクト(function)】

関数ポインタ、メンバ関数ポインタ、関数オブジェクトを
同じように使える

#include <iostream>
#include <functional>

using namespace std;

void disp(int value)
{
    cout << value << endl;
}

int main()
{
    function<void(int)> func = disp;
    func(3);

    return 0;
}

【疑似乱数生成(minstd_rand, mt19937, ranlux24, uniform_int_distribution, uniform_real_distribution ...)】

メルセンヌ・ツイスタ法等での疑似乱数生成クラス

#include <iostream>
#include <ctime>
#include <random>

using namespace std;

int main()
{
    mt19937 mt_rand(static_cast<unsigned long>(time(0)));

    for (int i = 0; i < 100; i++)
        cout << mt_rand() % 10 << endl; // 0〜9の乱数生成

    return 0;
}

【正規表現(regex)】

Let's Boostさんのサンプル使用
http://www.kmonos.net/alang/boost/classes/regex.html

#include <iostream>
#include <regex>

using namespace std;

int main()
{
    string str = "The HTML tag <title> means that ...";
    regex  reg( "<[^>]+>" );
    smatch result;

    if (regex_search(str, result, reg)) {
        cout << "found (pos=" << result.position() << ")" << endl;
        cout << " ==> " << result.str() << endl;
    }

    return 0;
}

C++0x言語拡張まとめ