メタプログラミング
プログラミングを学んでいく中で知っていると便利な概念でもあるメタプログラミング。広い意味で言えばプログラミングコードを書くプログラミングで、各言語で様々な実装方法があります。
インタープリタ言語では比較的やりやすいのですが、文字列として出力したコードを評価(eval)して実行する実験を以前C言語でやったことがあります。
https://github.com/systemsblue/Eval-C-Function
といってもこれらをあまりメタプログラミングとは言うことはなく、一般的にメタプログラミングというと、C++のテンプレートを使ったコーディングを言うことが多いような気がします。
わかりやすい例としては、コンパイル時に静的に演算結果を出力するものがあります。
参考)
https://ja.wikipedia.org/wiki/%E3%83%86%E3%83%B3%E3%83%97%E3%83%AC%E3%83%BC%E3%83%88%E3%83%A1%E3%82%BF%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%9F%E3%83%B3%E3%82%B0
階乗を計算するプログラムですが、これはコンパイル時に計算してその結果を定数として変数に代入しています。
何が便利かというと、定義に変数を使うことによってコーディング量を大幅に少なくできます。しかしながらC++のテンプレートはバージョンによって記法もいろいろとあることから難易度が高く学習コストが高いです。それゆえわかりやすいものから少しづつ学ぷ必要があります。C++の実行環境もコンソールを使うなど難しさに拍車をかけているますが、今回これをWebで手軽にできる環境を使用しました。
https://godbolt.org/
これでいろいろなコードをすぐ実行できるので学習するためのハードルはかなり下がります。
次のプログラムは、Aはタイプを条件で変更するテスト、Bは、オブジェクト指向言語では通常変数の型によって関数をかき分けるところを型によって処理を分岐したテストです。
参考)
https://izadori.net/cpp-templ-sfinae/
https://in-neuro.hatenablog.com/entry/2017/08/09/212808
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 |
#include<iostream> // A template<bool Cond, typename Then, typename Else> struct if_; template<typename Then, typename Else> struct if_<true, Then, Else> { typedef Then type; }; template<typename Then, typename Else> struct if_<false, Then, Else> { typedef Else type; }; struct ok{}; struct ng{}; typedef typename if_<true, ok, ng>::type answer; // B template <typename T> T func(T v) { if constexpr(std::is_integral_v<T>) { std::cout << "integer" << std::endl; return(v*2); } else if constexpr(std::is_floating_point_v<T>) { std::cout << "float" << std::endl; return(v*2); } else { std::cout << "string" << std::endl; return(v); } } std::ostream& operator<<(std::ostream& os, const answer& a) { os << typeid(a).name(); return os; } int main() { //A answer a; std::cout << a << std::endl; //B std::cout << func(1) << std::endl; std::cout << func(2.0) << std::endl; std::cout << func("abc") << std::endl; } |
こういったものを一つ一つ学習して、より高度な記述方法も学んでいきたいと思っています。
Category: 未分類