インスタンス化ではなくテンプレート定義でエラーが発生する理由について、他の回答は正しいです。
このようなものはどうですか?
template <unsigned int N, bool B = (N>=100)>
struct more_than_99;
template <unsigned int N>
struct more_than_99<N,true>
{};
int main()
{
more_than_99 <0> c; // error: implicit instantiation of undefined template 'more_than_99<0, false>'
}
もう少し堅牢にするため、および誤って more_than_99<0,true>
をインスタンス化するのを防ぐために 、これも機能します (C++11):
template <unsigned int N, bool B>
struct _impl_more_than_99;
template <unsigned int N>
struct _impl_more_than_99<N,true>
{};
template <unsigned int N>
using more_than_99 = _impl_more_than_99<N, (N>=100)>;
int main()
{
more_than_99 <0> c; // error: implicit instantiation of undefined template '_impl_more_than_99<0, false>'
}
エラーメッセージは _impl_
を参照していますが、 タイプしてください。
_impl_
を隠すことができます 詳細名前空間か何かで、 more_than_99
を文書化するだけです あたかも実際の型であるかのようにエイリアスします。
ただし、_impl_more_than_99<0,true>
の悪意のあるインスタンス化を防ぐことはできません。 .
enable_if
クラスの特殊化 (または関数のオーバーロード) がある場合は意味があります。 選択するために使用されます テンプレート パラメーターに応じて、ある実装と別の実装の間で、条件が満たされない場合にエラーをトリガーしないようにします。
アイデアは、「条件が満たされた場合はこの特殊化を有効にし、そうでない場合は特殊化されていないバージョンにフォールバックする」というものです。
あなたの場合、おそらく次のようなものが必要です:
#include <iostream>
#include <type_traits>
using namespace std;
template<unsigned int N, typename = void >
struct more_than_99
{
// Implementation if N <= 99
enum { value = false };
};
template <unsigned int N>
struct more_than_99<N, typename enable_if <N >= 100> :: type>
{
// Implementation if N >= 100
enum { value = true };
};
int main()
{
cout << more_than_99 <0>::value << endl; //false
cout << more_than_99 <100>::value << endl; //true
}
N
依存型の非型テンプレート パラメータではありません。 [temp.dep.temp]/p2
したがって、置換エラーが発生する代わりに、不正なコードから直接エラーが発生します。