基本的に、テスト変数msg.qty
がコンパイル時定数でない場合、これは不可能です。静的多型を達成するためにテンプレートを使用できる一方で、動的多型を達成するためにOOP(継承)を使用できることを理解する必要があります。つまり、実行時に仮想関数呼び出しが解決されている間は、コンパイル時にテンプレートが解決されます。両方を同時に使用できますが、同じ目的で使用することはできません(つまり、それぞれ独自のアプリケーションコンテキストを持つ補完的プログラミングパラダイムです)。あなたは、しかし、(enum
またはstatic const
として、すなわちMsg::qty
)タイプMsg
のコンパイル時定数であることをmsg.qty
を得ることができれば
は、その後、あなたはboost::enable_if
ライブラリを使用することができます。よう:
template <class Msg>
typename boost::enable_if<Msg::qty < 100, EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<short>(...); };
template <class Msg>
typename boost::enable_if<((Msg::qty >= 100) && (Msg::qty < 100000)), EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<int>(...); };
template <class Msg>
typename boost::enable_if<Msg::qty >= 100000, EncodedMsg<short> >::type*
encode(const Msg& msg) { return new EncodedMsd<long>(...); };
しかし、あなたが判断できた場合に、特定のクラスのメッセージのために、どのようなテンプレートのインスタンス化EncodedMsgに使用する、クラスの入れ子になったのtypedefとして定義する多くの方が簡単です次のようにメッセージは、あなたのエンコード機能を定義します。
template <class Msg>
Msg::encoded_type* encode(const Msg& msg) { return new Msg::encoded_type(...); };
また、あなたが変更できないメッセージクラスを持っている場合は、ネストされたのtypedefを定義するために(そのようなmessage_traitか何かのような)型特性を使用することができます。
しかし、msg.qtyが実行時の値にしかならない場合、動的多型を使用する(つまり、基本クラスまたはインタフェースへのポインタを返す)以外に選択肢はありません。またはboost::variant
を使用することもできます。
boost::variant< EncodedMsg<short>,
EncodedMsg<int>,
EncodedMsg<long> >* encode(const Msg& msg)
{
typedef boost::variant< EncodedMsg<short>,
EncodedMsg<int>,
EncodedMsg<long> > result_type;
if(msg.qty < 100)
return new result_type(EncodedMsg<short>(...));
else if(msg.qty < 100000)
return new result_type(EncodedMsg<int>(...));
else
return new result_type(EncodedMsg<long>(...));
};
上記の結果の型はEncodedMsgのテンプレートのインスタンス化の最大のと同じ大きさになりますが、あなたがそれを解決することができたという事実のようないくつかの明白な問題を(持っている:この場合、あなたはこれを行うことができますエンドレイドの追加レベル(EncodedMsgオブジェクトへのポインタの格納))。そして、それが多形的な代替案と同じくらい素晴らしいと効率的ではありません。