Usando SFINAE para detectar POD-ness de um tipo em C ++
O título original aqui eraolução para bug SFINAE no VS2005 C ++
Este é um uso provisório do SFINAE para fazer o equivalente à classe de modelo is_pod que existe no TR1 (no VS2005 ainda não há TR1). Deve ter seuvalo member true quando o parâmetro do modelo é do tipo POD (incluindo tipos primitivos e estruturas feitas a partir deles) e false quando não é (como em construtores não triviais
template <typename T> class is_pod
{
public:
typedef char Yes;
typedef struct {char a[2];} No;
template <typename C> static Yes test(int)
{
union {T validPodType;} u;
}
template <typename C> static No test(...)
{
}
enum {value = (sizeof(test<T>(0)) == sizeof(Yes))};
};
class NonPOD
{
public:
NonPod(const NonPod &);
virtual ~NonPOD();
};
int main()
{
bool a = is_pod<char>::value;
bool b = is_pod<NonPOD>::value;
if (a)
printf("char is POD\n");
if (b)
printf("NonPOD is POD ?!?!?\n");
return 0;
}
O problema é que, não apenas o VS 2005 não possui TR1, ele não se importará com a união acima (que não deve ser válida quando o parâmetro do modelo não for um POD), portanto, aeb são avaliados como verdadeiros.
Obrigado pelas respostas postadas abaixo. Depois de ler atentamente eles (e o código), percebi que o que estava tentando fazer era realmente uma abordagem errada. A ideia era combinar o comportamento da SFINAE com uma adaptação ao modelo must_be_pod (que encontrei no livroImperfect C ++, mas também pode ser encontrado em outros lugares). Na verdade, isso exigiria um conjunto de regras bastante particular para o SFINAE, que não é o que o padrão define, obviamente. Afinal, isso não é realmente um bug no VS.