13

テンプレートメタプログラミングへの道をゆっくりと感じており、以下を実装する方法がわかりません。

// hpp file
enum MyEnum { Alive = 0, Dead };
class A {
    public:
        template<typename T, typename O, MyEnum ls>
        static int Register();
};

// elsewhere in the code...
A::Register<IType1, Type1, Dead>();

コンパイル時に、3番目のテンプレートタイプ(コンパイル時不変)がDeadまたはAliveのいずれかの列挙値であることがわかります。次のように、Register関数に2つの本体を定義することは可能ですか?

// desired hpp file
template<typename T, typename O, Alive>
int Register();

template<typename T, typename O, Dead>
int Register();

// corresponding desired .inc file
template<typename T, typename O, Alive>
int Register() { // Alive specific implementation ...  }

template<typename T, typename O, Dead>
int Register() { // Dead specific implementation ...  }

私は見てきました: 定数値を持つC++テンプレートの特殊化

しかし、私はそれをこの状況に適用する方法を理解することができませんでした。

4

2 に答える 2

13

テンプレート関数を部分的に特殊化することはできません。解決策は、それを構造体でラップすることです。

template<typename T, typename O, MyEnum ls>
struct foo;

template<typename T, typename O>
struct foo <T, O, Alive> {
  static int Register() {
    // ...
  }
};

template<typename T, typename O>
struct foo <T, O, Dead> {
  static int Register() {
    // ...
  }
};

template<typename T, typename O, MyEnum ls>
int Register() {
  return foo<T, O, ls>::Register();
}
于 2012-05-22T02:32:04.130 に答える
3

ここでのパーティーには非常に遅いですが。

これを行う方法は、概念的に単純で読みやすいと思います。列挙型のさまざまな値をさまざまなタイプ(名前空間内でクリーンに保つため)にして、(テンプレート)関数のオーバーロードを利用するだけです。

namespace State {
  struct Dead {};
  struct Alive {};
}

template<typename T, typename O>
int Register(State::Dead) {
   return 1;
}

template<typename T, typename O>
int Register(State::Alive) {
   return 2;
}

あなたはそれらをこのように呼びます:

int main() {
   Register<int,int>(State::Dead());
   Register<int,int>(State::Alive());
   return 0;
}
于 2017-02-09T09:55:10.430 に答える