35

疑わしいですが、おそらくRTTIを使用して、既存の型からプリミティブ型のテンプレートパラメータを抽出できるかどうかについて興味があります。

例えば:

typedef std::bitset<16> WordSet;

他の場所にハードコーディングせずに、上記のコードの番号16を抽出することは可能でしょうか?コンパイラ固有の実装は大歓迎ですが、私は特に興味がありg++ます。

4

5 に答える 5

51

通常、任意のテンプレート パラメーターを選択することはできません。

ただし、通常の方法は次のとおりです。

template<int N>
struct foo {
    static const int value = N;
};

およびタイプの場合

template<typename T>
struct foo {
    typedef T type;
};

foo<39>::valueその後、またはとしてアクセスできますfoo<int>::type

特定のタイプがある場合は、部分的なテンプレートの特殊化を使用できます。

template<typename>
struct steal_it;

template<std::size_t N>
struct steal_it< std::bitset<N> > {
    static const std::size_t value = N;
};

実際、型パラメーターについても同じ原則が可能です。steal_it< std::bitset<16> >::valueこれで、 (int ではなく size_t を使用することに注意してください!)のように、任意のビットセットを渡すことができます。Variadic many テンプレート パラメータがまだないため、特定のパラメータ数に制限し、steal_it テンプレートの特殊化を 1 から N までの数で繰り返す必要があります。もう 1 つの問題は、混合パラメータ (型と非型パラメータ)。これを解決するのはおそらく自明ではありません。

タイプがなく、そのオブジェクトしかない場合は、トリックを使用して、コンパイル時に値を取得できます。

template<typename T>
char (& getN(T const &) )[steal_it<T>::value];  

int main() {
    std::bitset<16> b;
    sizeof getN(b); // assuming you don't know the type, you can use the object
}

トリックは、関数テンプレートに型を自動推定させてから、文字配列への参照を返すことです。関数を定義する必要はありません。必要なのはその型だけです。

于 2008-11-19T07:53:58.087 に答える
1

の場合、メンバー関数std::bitsetを使用できます。size()

size_t sz = oh_my_word.size();  // sz is now 16

一般的なケースでは、同様の方法でサイズを返すメンバー関数を定義できます。

template <int N>
class Foo
{
public:
  int size() const { return N; }
};
于 2008-11-19T07:20:27.670 に答える
1

他の回答で述べたようにstd::bitset、メンバー関数を使用してサイズを取得できるためsize()、これは他のどのトリックよりも適切な選択であるはずです。

一般的なケースにはいくつかの提案があり、以下で提案するものとほぼ同じですが、それでもこちらの方が簡単だと思います。

template <template<std::size_t> typename T, std::size_t K>
auto extractSize(const T<K>&) {
    return K;
}

int main() {
    std::bitset<6> f1;
    std::bitset<13> f2;
    std::cout << extractSize(f1) << std::endl;
    std::cout << extractSize(f2) << std::endl;
}
于 2018-02-04T13:42:26.563 に答える