Оригинальное название здесь было Обход SFINAE ошибка в VS2005 C++Использование SFINAE для обнаружения POD-ность типа в C++
Это предварительное использование SFINAE сделать эквивалент для шаблонного класса is_pod, что существует в TR1 (в VS2005 пока нет TR1). Он должен иметь значение значение член 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), поэтому одновременно и b оценивают значение true.
Спасибо за ответы, размещенные ниже. После тщательного прочтения их (и кода) я понял, что то, что я пытаюсь сделать, действительно неверно. Идея состояла в том, чтобы комбинировать поведение SFINAE с адаптацией к шаблону must_be_pod (что я нашел в книге Imperfect C++, но его можно найти и в других местах). На самом деле для этого потребуется довольно определенный набор правил для SFINAE, которые не являются стандартными. В конце концов, это не ошибка в VS.
Я попытался использовать другой тип, а не пустую структуру, которую вы предложили, char *, безрезультатно. Я просто попытался использовать ваш пример, но он дает тот же результат (истинный как для POD, так и для не-POD). –
О enable_if, я рассматривал аналогичный подход, но это заставило бы меня вручную выбрать типы, которые являются/не являются POD, и мое предпочтение было бы дать это бремя для компилятора. –
Я также знаю, что Boost имеет шаблон аналогично is_pod (на самом деле, большая часть TR1 была вдохновлена Boost и, вероятно, это еще один пример), но я бы предпочел не добавлять зависимость от функции, которая в будущем должна быть частью стандарта в любом случае. –