使用SFINAE来检测C ++中的类型的POD [英] Using SFINAE to detect POD-ness of a type in C++

查看:157
本文介绍了使用SFINAE来检测C ++中的类型的POD的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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



这是暂时使用SFINAE等效于在TR1中存在的is_pod模板类(在VS2005中还没有TR1)。当模板参数是POD类型(包括原始类型和由它们构成的结构体)时,它的成立,如果不是这样(如非平凡构造函数)。

 模板< typename T> class is_pod 
{
public:

typedef char是;
typedef struct {char a [2];} No;

模板< typename C> static是test(int)
{
union {T validPodType;} u;
}
template< typename C>静态无测试(...)
{
}
枚举{value =(sizeof(test< T>(0))== sizeof
};

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\\\
);
if(b)
printf(NonPOD is POD?!?!?\\\
);
return 0;问题是,不仅VS 2005不具有TR1,它赢得了$不关心上面的联合(当模板参数不是POD时,它不应该有效),因此a和b的值都为true。






感谢您下面的答案。仔细阅读他们(和代码)后,我意识到,我想做的是一个错误的方法。这个想法是将SFINAE行为与模板* must_be_pod *(我在书不完美的C ++ 中找到,但是也可以在其他地方找到)的适配相结合。实际上,这将需要一个相当特殊的规则对SFINAE,这不是标准定义,显然。

解决方案

你的方法最大的问题是你不做SFINAE这里 - SFINAE仅适用于参数类型和返回类型。



但是,在标准中的所有SFINAE情境中,没有一个适用于您的情况。它们是




  • void,引用,函数或无效大小的数组

  • 不是类型

  • 指向引用,引用引用,对void的引用

  • 指向非类类型成员的指针

  • 模板值参数的无效转换

  • 函数类型的参数类型为void

  • const / volatile函数类型


这可能是为什么在Boost文档中:


没有一些(尚未指定)从编译器帮助
,ispod永远不会
报告类或结构是一个
POD;这总是安全的,如果可能
次优。目前(2005年5月)只有
MWCW 9和Visual C ++ 8有
必要的编译器_intrinsics。



The original title here was Workaround for SFINAE bug in VS2005 C++

This is tentative use of SFINAE to make the equivalent for the is_pod template class that exists in TR1 (In VS2005 there's no TR1 yet). It should have its value member true when the template parameter is a POD type (including primitive types and structs made of them) and false when it's not (like with non-trivial constructors).

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;
}

The problem is, not only VS 2005 doesn't have TR1, it won't care about the union above (which shouldn't be valid when the template parameter is not a POD), so both a and b evaluate to true.


Thanks for the answers posted below. After reading carefully them (and the code) I realized that what I was trying to do was really a wrong approach. The idea was to combine SFINAE behavior with an adaptation to the template *must_be_pod* (which I found in the book Imperfect C++, but it can be found in another places, too). Actually, this would require a quite particular set of rules for SFINAE, which are not what the standard defines, obviously. This is not really a bug in VS, after all.

解决方案

The biggest problem with your approach is you don't do SFINAE here - SFINAE only applies to parameter types and return type here.

However, of all the SFINAE situations in the standard, none applies to your situation. They are

  • arrays of void, references, functions, or of invalid size
  • type member that is not a type
  • pointers to references, references to references, references to void
  • pointer to member of a non-class type
  • invalid conversions of template value parameters
  • function types with arguments of type void
  • const/volatile function type

That's probably why in Boost documentation, there is:

Without some (as yet unspecified) help from the compiler, ispod will never report that a class or struct is a POD; this is always safe, if possibly sub-optimal. Currently (May 2005) only MWCW 9 and Visual C++ 8 have the necessary compiler-_intrinsics.

这篇关于使用SFINAE来检测C ++中的类型的POD的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆