ここでの通常の解決策は特性です。テンプレートをインスタンス化するのではなく、 forstd::plus
を定義するtraitsクラスに加えて、アイデンティティ要素(static const、初期化子を使用)、およびその他の必要なものをインスタンス化します。何かのようなもの:typedef
std::plus
struct OpTraitsAdd
{
typedef std::plus<int> Op;
static int const identity = 0;
};
struct OpTraitsMult
{
typedef std::multiplies<int> Op;
static int const identity = 1;
};
明示的な特殊化を使用して、標準の演算子から特性を取得することもできます。
template <typename Op> struct OpTraits;
template<>
struct OpTraits<std::plus<int> >
{
static int const identity = 0;
};
template<>
struct OpTraits<std::multiplies<int> >
{
static int const identity = 1;
};
この場合、演算子を介してクラスをインスタンス化し、必要に応じて使用OpTraits<Op>::identity
します。
もちろん、どちらの場合も、独立したクラスまたはテンプレートの特殊化として、必要なすべての特性を提供する必要があります。必要なID要素が0と1の2つだけの場合は、次のような方法で自動的に実行できる可能性があります。
template <bool idIs0> struct IdImpl;
template<>
struct IdImpl<false>
{
static int value = 1;
};
template<>
struct IdImpl<true>
{
static int value = 0;
};
template <typename Op>
struct Id
{
static int value = ItImpl<Op(1, 0) == 1>::value;
};
は一定のepxressionではないため、これはC++11より前では機能しません。Op(1, 0)
C++11についてはよくわかりません。Op::operator()
しかし、宣言されていれば、うまくconstexpr
いくはずだと思います
。(クライアントが提供する可能性のあるものも含めて、多くのオペレーターをカバーする必要がある場合にのみ、わざわざ試してみました。)