43

1つだけではなく、値の範囲に基づいてテンプレートを特殊化する方法はありますか?次のコードは有効なC++コードではないことは知っていますが、それは私がやりたいことを示しています。私は8ビットマシン用のコードを書いているので、intとcharを使用する場合の速度に違いがあります。

template<unsigned SIZE>
class circular_buffer {
   unsigned char buffer[SIZE];
   unsigned int head; // index
   unsigned int tail; // index
};

template<unsigned SIZE <= 256>
class circular_buffer {
   unsigned char buffer[SIZE];
   unsigned char head; // index
   unsigned char tail; // index
};
4

4 に答える 4

49

std :: conditionalを試してください:

#include <type_traits>

template<unsigned SIZE>
class circular_buffer {

    typedef typename
        std::conditional< SIZE < 256,
                          unsigned char,
                          unsigned int
                        >::type
        index_type;

    unsigned char buffer[SIZE];
    index_type head;
    index_type tail;
};

コンパイラがC++11のこの部分をまだサポートしていない場合は、Boostライブラリに同等のものがあります。

繰り返しになりますが、自分でロールするのは簡単です(クレジットはKerrekSBに送られます)。

template <bool, typename T, typename F>
struct conditional {
    typedef T type;
};

template <typename T, typename F>  // partial specialization on first argument
struct conditional<false, T, F> {
    typedef F type;
}; 
于 2012-06-13T16:33:23.003 に答える
33

追加のデフォルトboolパラメータを使用します。

// primary template handles false
template<unsigned SIZE, bool IsSmall = SIZE <= 256>
class circular_buffer {
   unsigned char buffer[SIZE];
   unsigned int head; // index
   unsigned int tail; // index
};

// specialization for true
template<unsigned SIZE>
class circular_buffer<SIZE, true> {
   unsigned char buffer[SIZE];
   unsigned char head; // index
   unsigned char tail; // index
};
于 2012-06-13T16:31:32.140 に答える
7

別の可能なオプション:

template <unsigned SIZE>
struct offset_size {
    typedef typename offset_size<SIZE - 1>::type type;
};

template <>
struct offset_size<0> {
    typedef unsigned char type;
};

template <>
struct offset_size<257> {
    typedef unsigned int type;
};

template<unsigned SIZE>
class circular_buffer {
   unsigned char buffer[SIZE];
   typename offset_size<SIZE>::type head; // index
   typename offset_size<SIZE>::type tail; // index
};

イデオネの例

于 2012-06-13T16:35:49.873 に答える
0

タイプの扱いがいかに面倒なのか嫌いなので、を活用してもう少しシンプルなものを提案しますconstexpr。このバリアントは、さまざまなタイプが必要ない場合にさまざまな動作を可能にし、値の片側だけでなく範囲内に収まる必要性に対処します。

template<bool> struct If;

constexpr bool InClosedRange(std::size_t Value, std::size_t Lower, std::size_t Upper)
{
    return (Lower <= Value) && (Value <= Upper);
}

// Usage:
template<size_t Width, If<true>>
class Foo;

template<size_t Width, If<InClosedRange(Width, 1, 41)>>
class Foo { /* ... */ };

template<size_t Width, If<InClosedRange(Width, 42, 142)>>
class Foo { /* ... */ };

インスピレーション:https ://stackoverflow.com/a/9516959/929315

于 2017-11-08T20:45:30.290 に答える