1

テンプレートを使用して「最新の C++ デザイン」のような型特性を使用して、型に可変サイズがあるかどうかを判断しようとしています。たとえば、文字列には可変サイズのストレージが必要ですが、int には固定サイズのストレージがあります。このコードは Microsoft C++ で動作しますが、現在 Mac に移植していて、次のエラーが発生します。

明示的な特殊化は現在のスコープでは許可されていません

これを専門化する正しい方法は何ですか?

template <typename T>
class MyTypeTraits
{
    template<class U> struct VariableLengthStorageTraits
    {
        enum { result = false };
    };
    template<> struct VariableLengthStorageTraits<std::wstring>
    {
        enum { result = true };
    };

public:
    enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
};
4

3 に答える 3

5

2003 C++ 標準では、囲んでいるクラス定義の外でのメンバー テンプレートの特殊化のみが許可されています。また、定義外の特殊化は、囲んでいるテンプレートの明示的な完全な特殊化でなければなりません。Microsoft C++ は、この点で非標準です。内側のテンプレートは外側のクラス テンプレート引数を必要としないため、外側のテンプレートから内側のテンプレートを移動するだけです。

template<class U> struct VariableLengthStorageTraits
{
    enum { result = false };
};

template<>
struct VariableLengthStorageTraits<std::wstring>
{
    enum { result = true };
};

template <typename T>
struct MyTypeTraits
{
    enum{ IsVariableLengthType = VariableLengthStorageTraits<T>::result };
};
于 2011-10-09T22:22:15.810 に答える
4

外部クラス定義内にネストされたクラスの特殊化を追加することはできません。ただし、内部の特性クラスを別のエンティティにする方が簡単で、再利用可能です。

#include <type_traits>

template <typename> struct has_variable_length;  // intentionally undefined!
template <> struct has_variable_length<std::wstring> : std::true_type  { };
template <> struct has_variable_length<int>          : std::false_type { };
// ...

template <typename T> struct MyTraits
{
  static const bool variable_length = has_variable_length<T>::value;
  // ...
};

必要に応じて、個々の特性クラスをdetail名前空間にラップできます。

于 2011-10-09T22:21:19.980 に答える
0

関数の特殊化をクラス外および .cpp ファイル内に移動すると、ヘッダーでは機能しません。

于 2012-06-25T00:57:01.307 に答える