クラスに型があるかどうかをコンパイル時に検出するために SFINAE を使用すると、これには派生型も含まれているようです。理想的には、列挙型の存在をテストしたいと思いますが、同じ効果を示しています。どちらのテストも一般的に機能しますが、クラスが型または列挙型を派生させる場合にも true を返します。
#include <iostream>
struct A { enum { IsTagged }; struct IsTaggedStruct{}; };
struct B :A {};
struct C {};
template< int > struct HasTag;
template< class TST >
struct Check
{
template< class T2 > static char (&Test( ... ))[1];
template< class T2 > static char (&Test( HasTag<T2::IsTagged>* ))[2];
//template< class T2 > static char (&Test( typename T2::IsTaggedStruct* ))[2];
static const bool value = sizeof(Test<TST>(0))==sizeof(char[2]);
};
int main(int argc, char* argv[])
{
std::cout << "Value A=" << Check< A >::value << std::endl;
std::cout << "Value B=" << Check< B >::value << std::endl;
std::cout << "Value C=" << Check< C >::value << std::endl;
return 0;
}
出力:
+ g++ -std=c++03 main.cpp
+ ./a.out
Value A=1
Value B=1
Value C=0
必要な出力は A=1、残り 0 のみです。もちろん、一度に有効になる列挙型または型のテストは 1 つだけです。C++03 を使用した GCC。
tl;dr: SFINAE では、型がクラスに存在するかどうかのテストは、派生クラスにも当てはまります。クラスそのものに制限するにはどうすればよいですか?