【问题标题】:C++ : how do I use type_traits to determine if a class is trivial?C++:我如何使用 type_traits 来确定一个类是否是微不足道的?
【发布时间】:2011-10-02 05:03:40
【问题描述】:

在 C++0x 中,我想确定一个类是否微不足道/是否具有标准布局,以便我可以使用 memcpy()、memset() 等...

我应该如何使用 type_traits 实现下面的代码,以便我可以确认一个类型是微不足道的?

template< typename T >
bool isTrivialType()
{
  bool isTrivial = ???
  return isTrivial;
}

注意:is_pod() 限制性太强:我希望我的班级有简单的构造函数等... ...为方便起见。

补充:我认为 std::is_standard_layout 可能会给我我正在寻找的东西。 1.如果我添加构造函数,它仍然返回true 2.如果我添加一个虚方法,它返回false 这是我需要确定是否可以使用memcpy()、memset()

编辑:来自 Luc Danton 的解释和下面的链接(澄清):

struct N { // neither trivial nor standard-layout
   int i;
   int j;
    virtual ~N();
};

struct T { // trivial but not standard-layout
    int i;
private:
    int j;
};

struct SL { // standard-layout but not trivial
    int i;
    int j;
    ~SL();
};

struct POD { // both trivial and standard-layout
    int i;
    int j;
};

让 memcpy() 开心:

// N -> false
// T -> true
// SL -> ??? (if there are pointer members in destructor, we are in trouble)
// POD -> true

所以看起来 is_trivial_class 是正确的:is_standard_layout 不一定是正确的......

【问题讨论】:

  • 它看起来像新添加的 std::is_standard_layout 可以做我想做的 - 不像 POD,我可以添加构造函数,它仍然会返回 true
  • 标准版面不太对;例如,std::vector 可能是标准布局,但使用memcpy 将是一个坏主意。

标签: c++ c++11 typetraits


【解决方案1】:

对于std::memcpy,类型可以简单地复制就足够了。来自 n3290, 3.9 Types [basic.types] 第 2 段:

对于普通可复制类型 T 的任何对象(基类子对象除外),无论该对象是否拥有类型 T 的有效值,构成该对象的底层字节(1.7)都可以复制到一个数组中字符或无符号字符。

以下段落还描述了普通可复制类型的其他有用属性(即不只是复制到 char 数组)。

std::is_trivially_copyable 是检测到这一点的特征。但是,在我撰写本文时,它并没有由例如实现。 GCC,因此您可能希望使用 std::is_trivial 作为后备(因为它需要一个简单的复制构造函数)。

我真的不推荐使用is_standard_layout,除非你真的知道你在做什么(例如在一个特定平台上的语言互操作性)这不是你想要的。 More information 关于什么琐碎和标准布局可能会帮助您指定您想要的确切要求。

【讨论】:

  • 谢谢你,Luc - 在调查了你的喜欢之后,我认为你有最好的答案 - 建议使用 std::is_trivial 作为 gcc 的后备!我会将 is_trivially_copyable 别名为 is_trivial,直到 gcc 实现它 - 这样,我可以在一个地方更新我的代码。
【解决方案2】:

C++11中POD的定义是:

POD 结构是一个非联合类,它既是普通类又是标准布局类,并且没有非 POD 结构、非 POD 联合(或此类类型的数组)类型的非静态数据成员)。

因此,除非您违反标准布局规则或类似性质的规则,否则is_pod 就足够了。如果你违反了标准布局规则,那么你就不能使用memcpymemset等等。

所以我不知道你为什么需要这个,除非你试图专门测试琐碎性。

【讨论】:

  • 一个 POD 足以满足标准布局。但是,它的限制太大了。例如,如果我添加一个构造函数,即使只是简单地设置一个成员,它也不再是 POD,但从技术上讲,如果我理解正确,它仍然具有标准布局(即,我可以安全地使用 memcpy 和 memset)。这就是问题所在:POD 似乎对我的需求过于严格。
猜你喜欢
  • 2013-02-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-03
  • 2011-07-28
  • 1970-01-01
相关资源
最近更新 更多