2012-07-12 6 views
7

はC++テンプレート関数プログラミングの一形態をプログラミングしていますか?そうであれば、C++ Template Metaprogrammingに関連するnon-tail再帰のためのstackoverflowのような落とし穴をいくつか行いますか?はC++テンプレート関数プログラミングの一形態をプログラミングプログラミング

this questionの階乗テンプレートの例では、標準的な関数型プログラミングだと思います。または類似点は表面的なものに過ぎないのでしょうか?

#include <iostream> 
using namespace std; 

template< int n > 
struct factorial { enum { ret = factorial< n - 1 >::ret * n }; }; 

template<> 
struct factorial<0> { enum { ret = 1 }; }; 

int main() { 
    cout << "7! = " << factorial<7>::ret << endl; // 5040 
    return 0; 
} 
+5

C++テンプレートは実際には非常に純粋な関数型プログラミング言語です(副作用はありません)。ほとんどの関数型言語と異なり、コンパイル時に完全に評価されるという特殊性があります。構文はあまり良くありません。それで、同じ種類のテクニックとアルゴリズムが、他のテクニックとアルゴリズムともマップされていることは理にかなっています。実際に、HaskellのサブセットをC++のテンプレートに「desugar」するプロジェクトが存在します。私はパフォーマンスの特徴/ "操作上の意味"についてはあまり知らない。 – glaebhoerl

+1

[boost :: phoenix](http://www.boost.org/doc/libs/1_50_0/libs/spirit/phoenix/doc/html/index.html)を見てください。 –

+2

これは間違いなく本当の質問です。ちょっと不器用です。 – Marcin

答えて

2

は関数型プログラミングのメタプログラミングですか?

テンプレートの展開には副作用がないため、純粋に機能します。

もしそうなら、C++テンプレートメタプログラミングに関連するnon-tail再帰のstackoverflowのような落とし穴をいくつか実行しますか?

絶対に。 Factorialは、スタックの前に結果がオーバーフローするので、これは良いデモンストレーションではありませんが、長い再帰は間違いなくコンパイラにエラーを引き起こす可能性があります。しかし興味深いことに、コンパイラは自動的にメモを取るようにテンプレートを実装する傾向があります。例えば、フィボナッチシリーズの純粋に記述された実装は、O(2^n)ではなくO(n)時間でコンパイルする傾向があります。

3

私は最良の答えは、2つの概念がまったく異なるものであると考えています。

  • C++テンプレートの両方と(パラメトリック多型)MLなどの関数型言語はgeneric programmingの例であり、それはいくつかの理にかなって:しかし、それは本当にここで私は考えることができるいくつかの重要なポイントがあり、助けにはなりませんそれらを1つの質問で一緒に言及する。学問分野では、Workshop on Generic Programmingでさえ、C++テンプレートやMLスタイルの関数型プログラミングを扱うことがよくあります。

    しかし、テンプレートメタプログラミングを使用すると、C++コードのコンパイル時に「評価」されるコードを書くことができ、非常に限られたタスクでのみ使用できます。一方、機能的なプログラムは通常、実行時に実行され、複雑なデータ構造を定義し、抽象化などを行うことができます(テンプレートメタプログラミングを使用していくつかのことを行うことができますが、

  • なぜファクタリアルの例はファンクショナルプログラミングの階乗に似ていますか?テンプレートのメタプログラミングを使用しているときは、(新しいタイプやテンプレートを定義するだけなので) "可変変数"を定義することはできません。したがって、テンプレートのメタプログラミングは機能プログラミングスタイルのように感じるかもしれません。

  • テンプレートメタプログラミングを使用して記述されたコードは、コンパイル時に評価されます。これは、ユーザーの入力に依存できないことを意味します。それはコンパイルされるかどうか(コンパイラは再帰の深さにいくつかの制限があり、しばらくしてからあきらめます)。一方、機能的なプログラムは、何らかの入力を受けて評価することができます(つまり、使用可能なすべてのスタックまたはメモリを使用して失敗する可能性があります)。機能的なプログラマのための

、私はAgdaようないくつかの関数型言語でも、コンパイル時に物事を評価することができることを知って、私は物事をシンプルに保つために優れていると思います!

+16

彼らは全く違うものではありません。 C++テンプレートメタプログラミングは関数型プログラミングです。 (もちろん逆ですが、実際はそうではありませんが) – glaebhoerl

+4

キーポイントはあなたのステートメントと矛盾します:C++テンプレートのメタプログラミングと関数型プログラミングは同じではありませんが、非常に近いです。実際には、Haskell(のサブセット)で機能的なプログラムを解析し、C++のコンパイル時に変換して実行することさえできます。例えば。それを行うことができるライブラリhttp://abel.web.elte.hu/mpllibs/metaparse/index.htmlを参照してください。 –

+1

あなたはどちらも良い点を出していますが、私はまだ彼らが高いレベルでは全く別のものだと言います。低レベルでは、(テンプレートメタプログラミングのような機能的スタイルのサブセットを使用する)いくつかの技術的側面を共有していますが、大きなイメージを検討したい場合にはそれほど有用な情報ではありません。 –

関連する問題