それぞれが4つのオーバーロードを持つ関数のセットを定義したいとします。最初のオーバーロードはタイプの単一のパラメーターをint32_t
取り、2番目int64_t
は、3番目uint32_t
と4番目を取りuint64_t
ます。関数ごとに、すべてのオーバーロードの実装が同じであるため、代わりに関数テンプレートを定義できます。
template <typename T>
void f(T t) {
// ...
}
ただし、これは4つのオーバーロードがある場合とは異なります。これは、インスタンス化に使用できる(整数)タイプごとに個別の関数があるためf
です。ただし、の実装の詳細はf
、他の整数型では機能しない可能性があるようなものです。これに対処するために、関数テンプレートを4つのオーバーロードされた関数でラップできます。
template <typename T>
void f_impl(T t) {
// ...
}
void f(int32_t value) { f_impl(value); }
void f(int64_t value) { f_impl(value); }
void f(uint32_t value) { f_impl(value); }
void f(uint64_t value) { f_impl(value); }
これは機能しますが、関数ごとにかなりの量のコードが必要です(4つの関数のオーバーロード+1つの関数テンプレート)。これを単純化する方法はありますか?
明確にするために、テンプレートを直接使用することは望ましくありません。これは、、、、および。以外のタイプに特化することは(実装上の理由またはその他の理由で)意味がないためint32_t
です。int64_t
uint32_t
uint64_t
私はstd::enable_if
すでに使用してみましたが、その問題は次の例で最もよく示されています。
#include <type_traits>
#include <iostream>
template <typename T>
struct is_supported_int {
static const bool value = false;
};
template <>
struct is_supported_int<int32_t> {
static const bool value = true;
};
template <>
struct is_supported_int<int64_t> {
static const bool value = true;
};
// ...
template <typename T, typename = typename std::enable_if<is_supported_int<T>::value, T>::type>
void f(T t) {
// ...
}
int main() {
short s = 42;
f(s);
}
私がエミュレートしようとしているオーバーロードのある元のバージョンとは異なり、この例はf
、の一致する関数のセットから除外されるため、コンパイルされませんshort
。
残念ながら、Rapptzが提案したように、この関数の実装の詳細は特定の型に対してのみ定義でき、すべての整数型に対しては定義できstd::is_integral<T>
ないため、どちらも役に立ちません。f