8

まず、次のようなものがあります。

class Test {
    std::vector<int> a, b;
    void caller(...) { callee(...); }
    void callee(...) { /* Do stuff with 'a' */ }
}

私が欲しかったのはcallee 、 vectorとまったく同じ機能を持つことbです。これを行うには、2 つの明白な解決策があります。

  • ベクトルaまたはb引数として渡します。ただし、callee何百もの呼び出しに使用できる再帰関数であり、ベクトルを引数として渡すと、不要なオーバーヘッドになります。
  • 関数をコピーしてcalleevector を使用します。これは非常に長い関数であり、多くの重複コードがあるbにもかかわらず、最良の代替手段です。callee

好奇心から、テンプレート部分を探しに行ったところ、次の目的で使用できることに気付きました

左辺値参照型

ポインタ型

メンバー型へのポインター

だから私はこれをやろうとしました:

class Test {
    std::vector<int> a, b;
    void caller(...) { callee<a>(...); }
    template <std::vector<int> &x> void callee(...) { /* Do stuff with 'x' */ }
}

しかし、私は得る

エラー: 定数式で 'this' を使用しています

参照またはポインタを使用してこれを達成する方法はありますか?

ちなみに、私が欲しいのは、関数スコープとして見ることができます#define

4

4 に答える 4

9

配列やタプルもあるけど、古き良きメンバーへのポインターは好きじゃない?

class Test {
    std::vector<int> a, b;

    void caller(/*...*/) { callee<&Test::a>(/*...*/); }

    template <std::vector<int> Test::*vec>
    void callee(/*...*/) { /* Do stuff with `(this->*vec)` */ }
};
于 2016-11-03T13:41:25.750 に答える
4

データ メンバーへの参照をテンプレート引数として使用することはできません。テンプレートはコンパイル時であり、の値はthis実行時までわかりません。つまり、 type のランタイム オブジェクトごとに個別のインスタンス化 (個別のバイナリ コード) が必要になりますTest

あなたができるaことは、 andを配列に置き換え、この配列にインデックスbでテンプレート化することです:callee

class Test {
    std::array<std::vector<int>, 2> ab;
    void caller(...) { callee<0>(...); }
    template <size_t idx>
    void callee(...) { /* Do stuff with 'ab[idx]' */ }
}

このようにして、コンパイル時に索引付けが行われた (または少なくとも実行可能になった) 状態で、 2 つのインスタンス化callee( 用0と 用に 1 つ) のみを取得します。1

于 2016-11-03T13:08:53.533 に答える
2

単純にファサードを使用します。

class Test {
    std::vector<int> a, b;
    void caller_a(...) { callee(a); }
    void caller_b(...) { callee(b); }
    void callee(std::vector<int> &a_or_b, ...) {
    }
}

callee()いずれかのクラス メンバとして渡されるパラメータを参照します。

于 2016-11-03T12:39:07.923 に答える
1

@Angew の回答と同じロジックで、std::tuple を使用することもできます。タプルを使用すると、呼び出し先関数でさまざまな種類のコンテナーを使用することもできるので、非常に興味深いです。

class Test {
    std::tuple<std::vector<int>, std::list<int> > ab;
    void caller(...) { callee<0>(...); }
    template <size_t idx>
    void callee(...) { 
    ...
    auto aIt = std::get<idx>(ab).begin(); // gets either the vector or the list depending on template value
    ...
    }
}
于 2016-11-03T13:25:35.237 に答える