10

ユニバーサル参照パラメーターを取る関数テンプレートを特殊化するにはどうすればよいですか?

foo.hpp:

template<typename T>
void foo(T && t)    // universal reference parameter

foo.cpp

template<>
void foo<Class>(Class && class) {
    // do something complicated
}

ここで、Classはもはや推定型ではなく、したがってClass正確です。になることはあり得ないClass &ので、参照の折りたたみルールはここでは役に立ちません。おそらく、パラメーターを取る別の特殊化を作成できますがClass &(よくわかりません)、fooすべてのパラメーターの右辺値/左辺値参照の可能な組み合わせごとに含まれるすべてのコードを複製することを意味します。これは、ユニバーサル参照が回避することになっているものです。 .

これを達成する方法はありますか?

問題を解決するためのより良い方法がある場合に備えて、私の問題をより具体的に説明するには:

複数のゲーム サーバーに接続できるプログラムがあり、ほとんどの場合、各サーバーはすべてを同じ名前で呼び出します。ただし、いくつかの点でわずかに異なるバージョンがあります。これらのものには、移動、アイテムなど、いくつかの異なるカテゴリがあります。私は、内部コードが呼び出す関数の一般的な種類の「文字列を移動して列挙型を移動する」関数セットを作成しました。機能。ただし、一部のサーバーは、通信する独自​​の内部 ID を持ち、文字列を使用するサーバーもあれば、さまざまな状況で両方を使用するサーバーもあります。

ここで私がやりたいことは、これをもう少し一般的なものにすることです。

のようなものを呼び出せるようにしたいServerNamespace::server_cast<Destination>(source)Moveこれにより、 aから astd::stringまたはにキャストできますServerMoveID。内部的には、一部のサーバーでは送信されたメッセージの履歴を保持する必要があるため、コピーを作成 (または移動) する必要がある場合があります。ユニバーサル参照は、この問題に対する明らかな解決策のようです。

私が今考えているヘッダーファイルは、これを単純に公開します:

namespace ServerNamespace {

template<typename Destination, typename Source>
Destination server_cast(Source && source);

}

また、実装ファイルは、すべての正当な変換をテンプレートの特殊化として定義します。

4

2 に答える 2

2

私の意見では、実際のタイプではなくタグをオーバーロードするタグディスパッチシステムを使用するのが最善の解決策です。

struct foo {
    struct tag {};
};

struct bar {
    struct tag {};
};

template<typename Destination, typename Source>
Destination server_cast(Source && source, foo::tag) {
    // foo
}

template<typename Destination, typename Source>
Destination server_cast(Source && source, bar::tag) {
    // bar
}

template<typename Destination, typename Source>
Destination server_cast(Source && source) {
    return server_cast<Destination>(std::forward<Source>(source), typename std::remove_reference<Source>::type::tag());
}
于 2012-11-30T22:48:26.060 に答える
1

最も拡張可能なのは、テンプレート クラスの特殊化を作成することです。

template< class X > struct Whatever {
    void f(){ ... }
};

template<> struct Whatever<UserType> {
    void f(){ ... }
};

これが最も拡張可能であると私が言う理由は、Whatever を定義するファイルの内部または外部のどこにでも特殊化を追加できるためです。

これは、Pubby が提案するタグ ディスパッチ ソリューションを補完するものであり、排他的ではありません。

于 2012-11-30T23:02:21.983 に答える