7

次のようなコードがたくさんあります。

#define WITH_FEATURE_X

struct A {
#ifdef WITH_FEATURE_X
  // ... declare some variables Y
#endif
  void f ();
};

void A::f () {
  // ... do something
#ifdef WITH_FEATURE_X
  // ... do something and use Y
#else
  // ... do something else
#endif
  // ... do something
}

#defines をテンプレート パラメーターに置き換えたいと思います。

template < int WITH_FEATURE_X > // can be 0 or 1
struct A;

しかし、パラメーターに依存する数行だけのために、 A::f() の A<0>::f() および A<1>::f() のコード全体をほぼ複製したくありません。また、以前の #ifdef の代わりに関数を呼び出したくありません。一般的な解決策は何ですか?

4

4 に答える 4

2

関数のロジックの重複を避けたい場合は、テンプレート メソッド パターンfを使用できます(いいえ、そのような.template

template <bool enabled>
class helper {
protected:
    void foo() { /* do nothing */ }
};

template <>
class helper<true> {
protected:
    Y y;
    void foo() { /* do something with y */ }
};

struct A : private helper<WITH_FEATURE_X> {
    void f() {
        // common stuff

        foo(); // optimized away when WITH_FEATURE_X is false

        // more common stuff
    }
};
于 2010-09-01T07:41:18.350 に答える
1

あなたが望むのは、D言語に存在する「静的if」コマンドに相当すると思います。残念ながら、C++ にはそのような機能はありません。

コードの一部がリクエストの機能によって異なる場合、これらの部分は生のアルゴリズムの一部ではないため、メイン関数には属さないことに注意してください。したがって、関数でそのような機能を委任するオプションは、良いもののように思えます。

編集
#ifdef ステートメントを使用して同じサブタスクを別の方法で実行する場合は、サブ関数を定義するのが正しいことです。コードが読みやすくなりますが、読みにくくはなりません。

それらがまったく異なるアクションに使用されている場合、コードはすでに雑然としています。そのために何かをする。

発生する可能性があるパフォーマンスの問題については、コンパイラを信頼してください。

EDIT2
コードの最初の部分への答えに言及するのを忘れていました。次のトリックを使用して、「機能」に応じてメンバーを追加または削除します。

namespace helper
{
  template<int feature>
  struct A;

  template<>
  struct A<0> { // add member variables for case 0 };

  template<>
  struct A<1> { // add member variables for case 1 };
}

template<int feature>
class A : private helper::A<feature>
{
  // ... functions here
};
于 2010-09-01T06:22:27.213 に答える
0

一般的なコードの重複のポイントがわかりません。テンプレート パラメーターを使用している場合は、#ifdef を if(WITH_FEATURE_X) に置き換えるだけです。コンパイラによるコードの肥大化について話しているのですか。#ifdef を置き換えようとしているので、いつでも A<0> または A<1> を使用していると思います。そのため、コンパイラによってもコードが肥大化することはありません。

于 2010-09-01T07:16:48.050 に答える
0

一般的な解決策は、#ifdef を使用することです。:-)

于 2010-09-01T06:25:17.533 に答える