2

次のようなテンプレート クラスを考えてみましょう。

template <int opt1 = 1,
          bool opt2 = false,
          bool opt3 = true,
          int opt4 = 50>
class X  { };

パラメータを 1 つだけ変更しようとしましたが、C++ ではそれができないようです。それとも私が間違っていますか?このようなことを達成する方法:

X<opt2 = true> x;
4

2 に答える 2

2

R. Martinho Fernandesが言及したBoostバージョンは、次のように機能します。

  1. いくつかのオプションタイプを定義します(空のタグ構造にすることもbool、有効化/無効化するためにテンプレート化することもできます)。

    template <int I>  struct option_1: public std::integral_constant<int, I>  {};
    template <bool B> struct option_2: public std::integral_constant<bool, B> {};
    template <bool B> struct option_3: public std::integral_constant<bool, B> {};
    template <int I>  struct option_4: public std::integral_constant<int, I>  {};
    
  2. デフォルト値のある種のタイプリストを定義します(既存のテンプレートクラスと一緒に名前空間に非表示にします)

    namespace impl {
      typedef typelist<option_1<1>, option_2<false>,
                       option_3<true>, option_4<50>> X_defaults;
    
      template <int opt1, bool opt2, bool opt3, int opt4>
      class X { /* ... */ };
    }
    
  3. get適切なタイプリストからオプションを抽出するメカニズムを作成します(提供されたデフォルトにフォールバックするバージョンを含む)

    それがすべてできたら、すべてのオプションを処理し、既存のクラスに委任するラッパークラスを作成できます。

    template <typename... Options>
    class X: public impl::X<
        get<option_1, typelist<Options...>, impl::X_defaults>::value,
        get<option_2, typelist<Options...>, impl::X_defaults>::value,
        get<option_3, typelist<Options...>, impl::X_defaults>::value,
        get<option_4, typelist<Options...>, impl::X_defaults>::value>
    {
    };
    

最終的な呼び出しは次のようになります。

X<option_2<true>> x;

typelistと部分は、OP、親切に合格した編集者、または時間があれば私のgetための演習として(多くのエラーとともに)残されています。

于 2012-11-22T16:09:36.280 に答える
2

これを試して:

// opt1 = 1 (provided), opt2 = true (provided), opt3 = true (default), opt4 = 50 (default)
X<1, true> x;

2 番目のパラメーターのデフォルト値を変更する場合は、前のパラメーターの値も指定する必要があります。名前でパラメーターを参照することはできません。パラメーターには名前と位置があります。実際には、宣言に名前を付ける必要はまったくありません。

template <int = 1,
      bool = false,
      bool = true,
      int = 50>
class X  { };

このため、パラメーター リストの途中でパラメーターの既定値を定義することはできません。

void f(int a, int b = 0, int c); // Error!

前の関数宣言が正当であった場合、この呼び出しは何をしますか?:

f(1, 2);

または?fで呼び出します。a = 1, b= 0, c = 2a = 1, b = 2, c = unknown

于 2012-11-22T14:51:49.860 に答える