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

compile-time-polymorphism(コンパイル時多態)

東方算程譚 - アヒルの判別


すばらしいとしか言いようがない

しびれるな〜



さすがはC++


#include <iostream>
#include <string>

using namespace std;

// カテゴリ
struct cpp_category {};
struct java_category {};

// C++プログラマ
struct cpp_programmer {
    typedef cpp_category category;
    string language() const { return "C++ : "; }
};

// Javaプログラマ
struct java_programmer {
    typedef java_category category;
    string language() const { return "Java : "; }
};


// ジェネリックプログラミングに何を使う?
template <class Programmer>
void generic_programming_(const Programmer& programmer, cpp_category)
{
    cout << programmer.language() << "template" << endl;
}

template <class Programmer>
void generic_programming_(const Programmer& programmer, java_category)
{
    cout << programmer.language() << "Generics" << endl;
}


template <class Programmer>
void generic_programming(const Programmer& programmer)
{
    generic_programming_(programmer, typename Programmer::category());
}

int main()
{
    generic_programming(cpp_programmer());  // C++はtemplate
    generic_programming(java_programmer()); // JavaはGenerics
    return 0;
}

カテゴリ汎用化版

#include <iostream>
#include <string>

using namespace std;

// カテゴリ
struct cpp_category {};
struct java_category {};

// C++プログラマ
struct cpp_programmer {
    string language() const { return "C++ : "; }
};

// Javaプログラマ
struct java_programmer {
    string language() const { return "Java : "; }
};


// カテゴリを汎用化(category型を持っていないクラスも使えるようにする)
template <class Type>
struct category_of {
    typedef typename Type::category type;
};

template <>
struct category_of<cpp_programmer> {
    typedef cpp_category type;
};

template <>
struct category_of<java_programmer> {
    typedef java_category type; 
};


// ジェネリックプログラミングに何を使う?
template <class Programmer>
void generic_programming_(const Programmer& programmer, cpp_category)
{
    cout << programmer.language() << "template" << endl;
}

template <class Programmer>
void generic_programming_(const Programmer& programmer, java_category)
{
    cout << programmer.language() << "Generics" << endl;
}


template <class Programmer>
void generic_programming(const Programmer& programmer)
{
    generic_programming_(programmer, typename category_of<Programmer>::type());
}


int main()
{
    generic_programming(cpp_programmer());  // C++はtemplate
    generic_programming(java_programmer()); // javaはGenerics
    return 0;
}