ふるお〜と!- FullAuto

AI・ロボットが普及しBI(ベーシックインカム)が早急に実現されることを願う元ニートのブログ

ふるお〜と!-FullAuto

【C++ テンプレート】 ポリシーに基づく設計と静的ポリモーフィズムの比較

IoTとかロボットにプログラムを組み込みするときにC++テンプレートメタプログラミングを使ってみたいよね
x86_x64 , Arm, RISC-VなどのCPU, GPU, FPGAで表面上は同じソースコードを使ってみたいわ

コードをコンパイル時に自動生成って怖くないですか?

えぇなにかあったときヤバイよ。可読性も失われるし。

でもソフトウェアにバグがあったときにヤバイ自動車でさえ先進的な企業はC++14を採用しているわ(AUTOSAR)

Pythonから呼び出すDeepLearningのC++ライブラリもテンプレートが使われているわ

というわけで、もはやC++ テンプレートは必須知識なんだけど...

テンプレートが激ムズじゃありませんかと。

再利用性のないクソコードを書くC++erにならないためにもテンプレートは必須知識ね

プロジェクトのソースコードのレベルはレベルの低い人に合わせるのではなく上に合わせるべきよ

私はレベルの低い人に合わせた再利用性のないクソコードプロジェクトにアサインされたくないわ

テンプレートは自由度が高く人によって実装が違う恐ろしい状態らしいですね

テンプレートの具体的な例もネット上に情報が全然ないのも一因かもね

オッケー テンプレートの例を作ってみよう

テンプレートの例

ポリシーのテンプレート

#include <iostream>

struct Dog {
    static void Print(const std::string& value)
    {
        std::cout << value << "dog" << std::endl;
    }
};

struct Cat {
    static void Print(const std::string& value)
    {
        std::cout << value << "cat" << std::endl;
    }
};

template <class SayPolicy>
struct Animal {
    void Say() const
    {
        SayPolicy::Print("I am ");
    }
};

int main(){
    Animal<Dog>().Say();
    Animal<Cat>().Say();
}

静的ポリモーフィズム(CRTP)

#include <iostream>

template <typename D>
struct Animal
{
    template <typename TI>
    void Say(const TI& input) {
        D* ptr = static_cast<D*>(this);
        ptr->Imp(input);
    }
};

struct  Dog : public Animal<Dog>
{
    template <typename TI>
    void Imp(const TI& input) {
        std::cout << input << "dog" << std::endl;
    }
};

struct  Cat : public Animal<Cat>
{
    template <typename TI>
    void Imp(const TI& input) {
        std::cout << input << "cat" << std::endl;
    }
};



int main(){
    Dog d;
    Cat c;
    d.Say("I am ");
    c.Say("I am ");
}

ビルド

$ g++ -std=c++17 main.cpp 

出力

I am cat
I am dog

どちらも出力は変わらない。
ポリシーに基づく設計はカスタマイズ性の高いクラスに使用される。
ポリシー基づく設計はHeterogeneous Dictionariesと組み合わせて実装される。
...
やっぱり難しい。