19

の有用性を理解しようとしてstatic_assertいます。設計を実施するのに役立つかどうか、もしそうならその方法を知りたいです。

テンプレート型のサイズに基づいて部分的に特殊化された別のテンプレート クラス内に独自の実装を隠す一般的なテンプレート クラスがあります。このデザインの概要は次のとおりです。

template <class T, size_t S = sizeof(T)>
struct Helper;

template <class T>
struct Helper<T, sizeof(long)>
{
    static T bar();
};

// ... other specializations ...

template <class T>
class Foo
{
public:

    T bar()
    {
        return Helper<T>::bar();
    }
};

Fooは、サイズがHelperTの特殊化によってサポートされている場合にのみサポートされます。たとえば、との両方がサポートされています。ただし、ユーザーが. 通常、Helperの特殊化が定義されていないため、エラーが発生しますが、これは意図された動作です。Foo<long>Foo<unsigned long>Foo<bool>bool

static_assertこのインターフェースのユーザーにより役立つエラーを提供するために、この設計で使用する方法はありますか?

さらに、サイズが正しい場合でも、ユーザーが特定のタイプを使用することを制限したいと考えています。たとえば、Foo<float>許可されるべきではありません。現在、これを強制する唯一の方法は、ドキュメントに太字のコメントを記載することです。:)

4

3 に答える 3

27

テンプレート クラスの特殊化に対してのみ機能する場合は、デフォルトのテンプレート クラスに静的アサートを発生させます。

template <class T, size_t S = sizeof(T)>
struct Helper
{
   static_assert(sizeof(T) == -1, "You have to have a specialization for Helper!" );
}

デフォルトのテンプレート クラスは、より適切な特殊化がない場合にのみ選択されるため、アサートが発生します。

同じ手法を使用して型を禁止できますが、静的アサート チェックに使用される別のテンプレート パラメーターが必要になります。

template <class T, class G = T, size_t S = sizeof(T)>
struct Helper
{
   static_assert(sizeof(G) == -1, "You have to have a specialization for Helper!" );
}

template <class G>
struct Helper<float,G>
{
   static_assert(sizeof(G) == -1, "You can't use float !" );
}

template <>
struct Helper<int>
{
 //This is a good specialization
};

次に、これらの変数で試すことができます。

Helper<bool> a;  //"You have to have a specialization for Helper!"
Helper<float> b; //"You can't use float !"
Helper<int> c;   //compiles OK
于 2013-07-16T14:31:23.717 に答える