C++ 使用SFINAE检测C+中类型的POD ness+;

C++ 使用SFINAE检测C+中类型的POD ness+;,c++,visual-studio-2005,sfinae,C++,Visual Studio 2005,Sfinae,这里的原始标题是 VS2005 C++中SFINAE错误的解决方法 这是SFINAE的尝试性使用,以使TR1中存在的is_pod模板类等效(在VS2005中还没有TR1)。当模板参数是POD类型(包括基元类型和由基元类型构成的结构)时,它的值成员应该为true,否则它的值成员应该为false(与非平凡构造函数类似) 模板类是\u pod { 公众: typedef char是; typedef结构{char a[2];}No; 模板静态是测试(int) { 联合{T validPodType;}

这里的原始标题是 VS2005 C++中SFINAE错误的解决方法

这是SFINAE的尝试性使用,以使TR1中存在的is_pod模板类等效(在VS2005中还没有TR1)。当模板参数是POD类型(包括基元类型和由基元类型构成的结构)时,它的值成员应该为true,否则它的值成员应该为false(与非平凡构造函数类似)

模板类是\u pod
{
公众:
typedef char是;
typedef结构{char a[2];}No;
模板静态是测试(int)
{
联合{T validPodType;}u;
}
模板静态无测试(…)
{
}
枚举{value=(sizeof(test(0))==sizeof(Yes))};
};
非食品级
{
公众:
非od(const NonPod&);
虚拟~NonPOD();
};
int main()
{
bool a=是pod::值;
bool b=是_pod::值;
如果(a)
printf(“char是POD\n”);
如果(b)
printf(“非POD就是POD?!\n”);
返回0;
}
问题是,不仅VS2005没有TR1,它也不关心上面的union(当模板参数不是POD时,union应该无效),因此a和b都计算为true



谢谢你在下面贴出的答案。在仔细阅读了它们(以及代码)之后,我意识到我所尝试的方法确实是错误的。我们的想法是把SIMAE行为与模板的自适应相结合(我在不完美的C++中找到,但是它也可以在其他地方找到)。事实上,这将需要一套非常特殊的SFINAE规则,显然这些规则不是标准所定义的。毕竟,这在VS中并不是一个真正的bug。

我不确定您在这里尝试执行SFINAE的方式,因为
is_pod::test(…)
也将匹配
is_pod::test(0)
。如果使用不同的类型而不是“int”,可能会得到更好的匹配:

template <typename T> class is_pod
{
  struct my_special_type { };
  public:
    typedef char Yes;
    typedef struct {char a[2];} No;

    template <typename C> static Yes test(my_special_type)
    {
      union {T validPodType;} u;
    }

    template <typename C> static No test(...)
    {
    }
    enum {value = (sizeof(test<T>(my_special_type())) == sizeof(Yes))};
};
模板类是\u pod
{
结构my_special_类型{};
公众:
typedef char是;
typedef结构{char a[2];}No;
模板静态是测试(我的特殊类型)
{
联合{T validPodType;}u;
}
模板静态无测试(…)
{
}
枚举{value=(sizeof(test(my_special_type())==sizeof(Yes));
};

您可能还想看看f来为您完成SFINAE——除非您正试图实现自己的库或出于某种原因。

这也不适用于VS2008,但我怀疑您也知道这一点。SFINAE用于推导模板参数的模板参数;即使您可以创建一个与另一个类型不兼容的类型(即,联合不能使用非POD),您也不能真正推断出某个类型的类型来揭示某个类型的构造函数特性


事实上,VS 2008使用编译器对traits的支持来实现
std::tr1::type_traits

您的方法的最大问题是您在这里不执行SFINAE-SFINAE仅适用于参数类型和返回类型

然而,在标准中的所有SFINAE情况中,没有一种适用于您的情况。是的

  • 无效、引用、函数或无效大小的数组
  • 不是类型的类型成员
  • 指向引用的指针,指向引用的引用,指向void的引用
  • 指向非类类型成员的指针
  • 模板值参数的转换无效
  • 参数类型为void的函数类型
  • 常量/易失性函数类型
这可能就是为什么Boost文档中有:

没有一些(尚未指明)帮助 从编译器来看,ispod永远不会 报告类或结构是 豆荚如果可能的话,这总是安全的 次优。目前(2005年5月)仅限 MWCW 9和Visual C++ 8都有 必要的编译器-_intrinsic


我尝试使用另一种类型,而不是您建议的空结构,使用char*,但没有效果。我只是试着使用你的例子,但它给出了相同的结果(对于POD和非POD都是如此)。关于enable_if,我考虑了一种类似的方法,但这会迫使我手动选择属于/不是POD的类型,我更喜欢将这种负担交给编译器。我也知道Boost有一个类似于is_POD的模板(事实上,TR1的大部分灵感来源于Boost,这可能是另一个例子),但我不想为将来应该成为标准一部分的特性添加依赖项。
template <typename T> class is_pod
{
  struct my_special_type { };
  public:
    typedef char Yes;
    typedef struct {char a[2];} No;

    template <typename C> static Yes test(my_special_type)
    {
      union {T validPodType;} u;
    }

    template <typename C> static No test(...)
    {
    }
    enum {value = (sizeof(test<T>(my_special_type())) == sizeof(Yes))};
};