C ++では、型以外のテンプレートパラメータを整数型または列挙型(ブール値と文字を含む整数型)、および任意の型へのポインタと参照にすることができます。
整数、ブール、および列挙型のパラメーターが広く使用されているのを見てきましたが、それらの有用性に感謝しています。文字列のコンパイル時の解析に文字パラメータを巧妙に使用することもあります。
しかし、任意の型へのポインターまたは参照である非型テンプレートパラメーターのいくつかのユースケースは何でしょうか?
C ++では、型以外のテンプレートパラメータを整数型または列挙型(ブール値と文字を含む整数型)、および任意の型へのポインタと参照にすることができます。
整数、ブール、および列挙型のパラメーターが広く使用されているのを見てきましたが、それらの有用性に感謝しています。文字列のコンパイル時の解析に文字パラメータを巧妙に使用することもあります。
しかし、任意の型へのポインターまたは参照である非型テンプレートパラメーターのいくつかのユースケースは何でしょうか?
メンバー関数へのポインターをテンプレート パラメーターとして使用すると、コンパイラーはその関数の呼び出しをインライン化できます。この使用例は、この質問に対する私の回答で見ることができます: How to allow templated functor work on both member and non-member functions
この例では、テンプレート パラメーター内のメンバー関数へのポインターにより、メンバー関数へのポインターへの呼び出し (インライン化) を含む「サンク」関数を生成できます。サンク関数へのポインターには、メンバー関数へのポインターとは異なり、最小限のランタイム コストで格納およびコピーできる汎用シグネチャ (および固定サイズ) があります。
コンパイル時にバッファのアドレスがわかっている場合は、特にmemcpyなどの場合、その配置に基づいて(コンパイル時に)決定を下すことができます。これにより、実行時のチェックをスキップして、すぐにジャンプできます。最も効率的なサイズのタイプを使用してデータをコピーします。
(私は推測しています)あなたはコンパイルすることもできるかもしれません-渡されたポインターがページアラインされていることを主張します(例えばnvmeプロトコルに役立ちます)が、それがどのように見えるかはわかりません。
重要なのは、pointer-template-argument がOperationsだと思います。 (より状況に応じた方法は関数ポインタであり、「より簡単な」方法は関数オブジェクトです[これは再び型です。])
template<typename Key, class Val, bool (*CMP)(Key const&, Key const&)>
class map
{
};
template<typename KEY, class VALUE, typename CMP = std::less<KEY>>
class map
{
public:
CMP cmp;
};
どの比較を事前に適用するかわからないため、コンテナーに組み込むことはできません。それを必要とする関数に外部から、またはテンプレートを介して提供する必要があります。
非整数テンプレート パラメータの便利な例を次に示します。いくつかの事前宣言 (すべてではありませんが、アイデアを得るには十分です):
template <bool flag, class T, class F> struct SelectType
{
typedef T Result;
};
template <class T, class F> struct SelectType<false, T, F>
{
typedef F Result;
};
#define PARAMETER( selector, type ) typename SelectType<TypeTraits<T>::selector, type,
#define PTR_TRAITS typename ::Linderdaum::Utils::TypeTraits<T>::PointeeType
#define REF_TRAITS typename ::Linderdaum::Utils::TypeTraits<T>::ReferredType
using namespace ::Linderdaum::Utils;
template <class T> struct ParameterType
{
typedef
PARAMETER( IsString, clStringParameter )
PARAMETER( IsReference, clPODParameter<REF_TRAITS> )
PARAMETER( IsPointer, clPointerParameter<PTR_TRAITS> )
PARAMETER( IsFundamental, clPODParameter<T> )
// default
clPODParameter<T>
>::Result
>::Result
>::Result
>::Result
Type;
};
そして実際の使用コード:
clParametersList Params;
ParameterType<const LString& >::Type Param0;
ParameterType<size_t >::Type Param1;
ParameterType<clDownloadCompleteCallback >::Type Param2;
Param0.ReadValue( &P0 );
Param1.ReadValue( &P1 );
Param2.ReadValue( &P2 );
Params.push_back( &Param0 );
Params.push_back( &Param1 );
Params.push_back( &Param2 );