3

私は、たくさんのテンプレートとそれらの専門分野で取り組む新しいプロジェクトに深く関わっています。さて、プログラミングをせずに1日を過ごした後、私はそれが本当に余分なコード行の価値があるかどうかを自問していることに気づきました。

問題は、専門化の利点は何ですか?

これは:

template <int i> class A {};
template <> class A <1> { void foo() {/* something */}  };
template <> class A <2> { void foo() {/* something else*/}  };
template <> class A <3> { void foo() {/* even different*/}  };

とにかくより良い(より速い実行)

template <int i> class A { 
   void foo() {
      if (i==1) {/* something */}
      else if (i==2) {/* something else*/}
      else if (i==3) {/* even different*/}
   }
};

編集:

このコードは、他の人が使用するライブラリの一部です。私はgcc4.6.3を使用していますが、最終的にはコードはさまざまなコンパイラで使用されます。

編集:

これらの2つのコードは、gcc4.6.3を使用して同一のバイナリになります。私の実際のコードは使用可能にはほど遠いため、完全なケースをテストすることはできません。それは本当に原則、汎用性、再利用性、保守性などの問題のようです...

4

4 に答える 4

6

ここでは速度は主要な問題ではありませんが、拡張性は主要な問題です。

特殊化には、コードのクライアントがの新しいオーバーロードを簡単に追加できるという利点がありますfoo()。後で次の新しい動作を追加することにしたとしますi=4。最初のアプローチでは、単に新しいスペシャライゼーションを追加します。2番目のバージョンでは、関数を変更する必要がありますfoo()。ライブラリをバイナリ形式でリリースした場合、クライアントは満足しません。

2番目のアプローチに対する特殊化アプローチの優先順位は、オープン/クローズド原則の明示です。コードは拡張のためにオープンであり、変更のためにクローズされている必要があります。

于 2012-07-01T20:00:35.517 に答える
2

これは、使用しているコンパイラによって異なります。私は自分でそのようなコードをたくさん書いています、そして私のコンパイラは私のために正しいことをします。ただし、C ++標準には、この点でコンパイラが賢いことを要求するものはないため、問題が発生する可能性があります。したがって、コンパイラが正しいことを実行することを確認してください。一般的な経験則として、他の人が使用することを目的とした再利用可能なライブラリを作成している場合、このコードを別のコンパイラやエキゾチックな環境に移植する予定がある場合などは、この機能に依存しないでください。

于 2012-07-01T19:43:17.723 に答える
2

「なぜテンプレートの特殊化が優れているのか」とおっしゃっていますが、なぜそれが悪いのかをお話しさせてください。のコードの少なくとも一部は一般的だと思いますi=1i=2そうi=3でなければ、なぜ同じ名前になるのですか?)。もしそうなら、あなたが専門化に行くときにいくつかのコードを複製しなければならないかもしれません、そしてそれはコードを維持するのを難しくします。

コードの重複はコンパイラに任せたほうがよいでしょう。コンパイラは、これらのif-elseif-else構造でかなりうまく機能します。あなたも持つことができますif (i<3)、それは専門化で実装するのは非常に厄介でしょう。

もちろん、関数がほぼ完全に異なる場合は、テンプレートの特殊化を使用するときにこの欠点はありません(そして利点があります)。

于 2012-07-01T20:11:53.497 に答える
2

i=1に対して有効なコードはに対して無効である可能性がありi=2、実行されない場合でもコンパイラがチョークするため、コードを1つの関数として記述できない場合があります。

例えば:

template <int i> class A { 
   void foo() {
      if (i==1)
      {
          cout << "Easy";
      }
      else if (i==2)
      {
          int stuff[100 * i - 110] = {42}; // error: negative array size for i=1
          cout << stuff[0];
      }
      else if (i==3)
      {
          /* even different*/
      }
   }
};
于 2012-07-01T20:51:59.187 に答える