ログ解析者がC++テンプレートプログラミングをかじった結果。。。

C++テンプレートプログラミングという技術がある。
聞くところには、Javaにはないという。。

ログ解析者にとっては、そのまんまだが、「えらく難しい。」(*´Д｀)

↓を読む。。。

C++テンプレートテクニック 第2版
https://www.sbcr.jp/product/4797376685/

ログ解析者にとっては、次の２つに集中することにする。

ポリシー -> Boost.MultiIndex　６章
Type Erasure -> boost::function　８章

テンプレートには。。。

関数テンプレート
クラステンプレート
メンバテンプレート
エリアステンプレート
変数テンプレート

がある。

まずは、関数テンプレートについて調べる。。

関数テンプレートとは、個人的には、引数の型によらず関数を書くものである。
→　intもdoubleも一度書いた関数で扱えるようにする。

コードを見てみる。。

     1#include <iostream>
     2using std::cout; using std::endl;
     3
     4#include <functional>
     5using std::less;
     6
     7#include <cstring>
     8using std::strcmp;
     9
    10template <typename T> int compare(const T &v1, const T &v2)
    11{
    12        cout << "FUNC1: compare(T)" << "\t";
    13        cout << " " << v1 << "," << v2 << endl;
    14
    15        if (less<T>()(v1, v2)) return -1;
    16        if (less<T>()(v2, v1)) return 1;
    17
    18        return 0;
    19}    20
    21template<unsigned N, unsigned M>
    22int compare(const char (&p1)[N], const char (&p2)[M])
    23{
    24        cout << "FUNC2: compare(const char arrays)" << "\t";
    25        cout << " " << p1 << "," << p2 << endl;
    26
    27        return strcmp(p1, p2);
    28}
    29
    30template<>
    31int compare(const char *const& p1, const char *const& p2)
    32{
    33        cout << "FUNC3: compare(const char*const)" << "\t";
    34        cout << " " << p1 << "," << p2 << endl;
    35
    36        return strcmp(p1, p2);
    37}
    38
    39int main()
    40{
    41        int *p1 = new int(45);
    42        int *p2 = new int(42);
    43
    44        cout << compare(*p1, *p2) << endl;
    45
    46        cout << "Pointer address:" << endl;
    47        cout << compare(p1, p2) << endl;
    48
    49        cout << "strcmp:" << strcmp("hello", "world!") << endl;
    50        cout << compare("hello", "world!") << endl;
    51
    52        const char *cp1 = "hello", *cp2= "world!";
    53        cout << compare(cp1, cp2) << endl;
    54
    55        const char *cp3 = "hello", *cp4= "hello";
    56        cout << compare(cp3, cp4) << endl;
    57
    58        return 0;
    59}

https://github.com/RuoAndo/qiita/blob/master/compare_by_template.cpp

ベースとなる部分がこちらで、これでv1,v2がintであろうとdoubleであろうと処理できる。

    10template <typename T> int compare(const T &v1, const T &v2)
    11{
    12        cout << "FUNC1: compare(T)" << "\t";
    13        cout << " " << v1 << "," << v2 << endl;
    14
    15        if (less<T>()(v1, v2)) return -1;
    16        if (less<T>()(v2, v1)) return 1;
    17
    18        return 0;
    19}    

↓は、まだあまり慣れていないが、、[N] [M]と、引数（整数）を取ることができる。

    21template<unsigned N, unsigned M>
    22int compare(const char (&p1)[N], const char (&p2)[M])
    23{
    24        cout << "FUNC2: compare(const char arrays)" << "\t";
    25        cout << " " << p1 << "," << p2 << endl;
    26
    27        return strcmp(p1, p2);
    28}

↓は、空の<>があるもので、特殊化というらしい。
引数にchar *が来たときは別の処理(strcmp)をしてくれというものである。

    30template<>
    31int compare(const char *const& p1, const char *const& p2)
    32{
    33        cout << "FUNC3: compare(const char*const)" << "\t";
    34        cout << " " << p1 << "," << p2 << endl;
    35
    36        return strcmp(p1, p2);
    37}

↓では、47行目と50行目では別の関数 FUNC1/FUNC3が呼ばれるが、これはコンパイル時に決定される。

    47        cout << compare(p1, p2) << endl;

    50        cout << compare("hello", "world!") << endl;

実行してみる。。。

<pre>
$ ./a.out 
FUNC1: compare(T)        45,42
1
Pointer address:
FUNC1: compare(T)        0x5637c7a20e70,0x5637c7a20e90
-1
strcmp:-1
FUNC2: compare(const char arrays)        hello,world!
-15
FUNC3: compare(const char*const)         hello,world!
-15
FUNC3: compare(const char*const)         hello,hello
0
</pre>

（｀ー´）b

テンプレート関数では、一致していない場合、-1(strcmp)ではなく-15を返しているが、さほど問題ないと思ふ。