2

私の質問に関連する例を探していましたが、まだ解決策が見つかりません。私が見つけた最も近いものは

テンプレート引数としてのテンプレート関数

必要に応じて実際の例を投稿しようとしますが、これまでのコードの一部には次のものが含まれています。

template<class InterfaceType, class T> 
inline void write_info(InterfaceType& interface, T& t) {
    InterfaceType::write_info(interface, t);
}

template<class InterfaceType, class T> 
inline void write_data(InterfaceType& interface, T& t) {
    InterfaceType::write_data(interface, t);
}

template<class InterfaceType, class T> 
inline void write_definition(InterfaceType& interface, T& t) {
    InterfaceType::write_definition(interface, t);
}

テンプレートは、 (静的メソッド)write_infoと呼ばれるメソッドを持つインターフェイス タイプに依存することに注意してください。write_infoこれが行われる理由は、write_info後で何も再定義しなくても、特定のデータ型に関数を特化できるためInterfaceTypeです。

簡単な質問は次のとおりです。関数を関数パラメーターとして指定するテンプレートを使用して、上記のコードを削減できますか? 特殊なデータ型に対してこれら 3 つの関数をすべて定義することを避けることができるように、これを可能にしたいということを心に留めておいてください。

がとの 2 つの属性をfoo持つ構造体であるとします。次に、上記の関数を次のように特殊化できます。int adouble b

template<class InterfaceType> 
inline void write_info(InterfaceType& interface, foo& t) {
    InterfaceType::write_info(interface, t.a);
    InterfaceType::write_info(interface, t.b);
}

template<class InterfaceType> 
inline void write_data(InterfaceType& interface, foo& t) {
    InterfaceType::write_data(interface, t.a);
    InterfaceType::write_data(interface, t.b);
}

template<class InterfaceType> 
inline void write_definition(InterfaceType& interface, foo& t) {
    InterfaceType::write_definition(interface, t.a);
    InterfaceType::write_definition(interface, t.b);
}

ご覧のとおり、同じコードを何度も書いています。write_infoここでは、InterfaceType にすでに define 、for 、write_dataおよびがあると想定しています。何か案は?write_definitionintdouble

4

1 に答える 1

5

ロジックを変えてください: 型ごとに特化しwrite_thingたオーバーロードを記述するのではなく、任意の関数を各型のオブジェクトに適用する単一の関数を記述してから、単純に にデリゲートするapplyそれぞれの単一のオーバーロードを作成します。write_thingapply

// Define a catch-all apply that handles "everything else"
template <typename Interface, typename Function, typename Object>
void apply(Interface& i, Function f, Object& x) {
    f(i, x);
}

// Define overloads for "apply" that handle special cases
template <typename Interface, typename Function>
void apply(Interface& i, Function f, foo& x) {
    f(i, x.a);
    f(i, x.b);
}

// Define polymorphic adapters for your write_[thing] functions:
struct write_info_impl {
    template <typename Interface, typename Object>
    void operator()(Interface& i, Object& x) const {
        Interface::write_info(i, x);
    }
};

// Then implement your write_[thing] functions in terms of the above:
template <typename Interface, typename Object>
void write_info(Interface& interface, Object& x) {
    apply(i, write_info_impl(), x);
}
于 2012-09-26T17:36:26.240 に答える