Первоначальное название здесь было Обходной путь для ошибки SFINAE в VS2005 C ++.
Это предварительное использование SFINAE для создания эквивалента для класса шаблона is_pod, который существует в TR1 (в VS2005 еще нет TR1). Его член value должен иметь значение true, если параметр шаблона является типом POD (включая примитивные типы и структуры, созданные из них), и false, когда это не так (например, с нетривиальными конструкторами).
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;
}
Проблема в том, что не только VS 2005 не имеет TR1, он не заботится о приведенном выше объединении (которое не должно быть действительным, если параметр шаблона не является POD), поэтому оба значения a и b имеют значение true.
Спасибо за ответы, размещенные ниже. Внимательно прочитав их (и код), я понял, что то, что я пытался сделать, было действительно неправильным подходом. Идея заключалась в том, чтобы объединить поведение SFINAE с адаптацией к шаблону must_be_pod (который я нашел в книге Imperfect C ++, но его можно найти и в других местах). Фактически, это потребует совершенно определенного набора правил для SFINAE, которые, очевидно, не являются тем, что определяет стандарт. В конце концов, это не совсем ошибка в VS.