管理琐碎的类型 [英] Managing trivial types

查看:86
本文介绍了管理琐碎的类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我发现C ++中琐碎类型的复杂性是不容易理解的,希望有人能启发我以下内容。

I have found the intricacies of trivial types in C++ non-trivial to understand and hope someone can enlighten me on the following.

给定类型 T ,使用 :: operator new(std :: size_t) T 存储>或 :: operator new [](std :: size_t) std :: aligned_storage void * p 指向该存储中与 T 适当对齐的位置,以便可以在 p :

Given type T, storage for T allocated using ::operator new(std::size_t) or ::operator new[](std::size_t) or std::aligned_storage, and a void * p pointing to a location in that storage suitably aligned for T so that it may be constructed at p:


  1. 如果 std :: is_trivially_default_constructible< T> :: value 成立,是代码在 p 跳过 T 的初始化时调用未定义行为的行为(即通过使用 T * tPtr = new(p)T(); ),然后以其他方式访问 * p 作为 T

  2. < T * tPtr = static_cast< T *>(p); 可以而不用担心不确定的行为吗? li>如果 std :: is_trivially_destructible< T> :: value 成立,则会跳过 T 在<$ c处的销毁$ c> * p (即通过调用 tPtr->〜T(); )导致未定义的行为?
  3. 对于任何类型 U ,其中 std :: is_trivially_assignable< T,U> :: value 成立,是 std :: memcpy(& t,& u,sizeof(U)); 等效于 t = std :: forward< U> (u); (对于任何类型为 T t > u 类型为 U )还是会导致未定义的行为?

  1. If std::is_trivially_default_constructible<T>::value holds, is the code invoking undefined behavior when code skips initialization of T at p (i.e. by using T * tPtr = new (p) T();) before otherwise accessing *p as T? Can one just use T * tPtr = static_cast<T *>(p); instead without fear of undefined behavior in this case?
  2. If std::is_trivially_destructible<T>::value holds, does skipping destruction of T at *p (i.e by calling tPtr->~T();) cause undefined behavior?
  3. For any type U for which std::is_trivially_assignable<T, U>::value holds, is std::memcpy(&t, &u, sizeof(U)); equivalent to t = std::forward<U>(u); (for any t of type T and u of type U) or will it cause undefined behavior?


推荐答案


  1. 不,您不能。该存储中没有任何类型为 T 的对象,就像访问未定义。另请参阅TC的答案在此

  1. No, you can't. There is no object of type T in that storage, and accessing the storage as if there was is undefined. See also T.C.'s answer here.

仅需澄清 [basic.life] / 1 ,表示具有空虚初始化的对象是从存储分配开始还活着:这种说法显然是指对象的初始化。使用 operator new malloc 分配原始存储时,没有初始化为空的对象,因此我们不能考虑它活着,因为它不存在。实际上,只有在定义了空虚初始化的情况下创建的对象才能在分配存储之后但在空虚初始化发生之前(即,遇到其定义)进行访问。

Just to clarify on the wording in [basic.life]/1, which says that objects with vacuous initialization are alive from the storage allocation onward: that wording obviously refers to an object's initialization. There is no object whose initialization is vacuous when allocating raw storage with operator new or malloc, hence we cannot consider "it" alive, because "it" does not exist. In fact, only objects created by a definition with vacuous initialization can be accessed after storage has been allocated but before the vacuous initialization occurs (i.e. their definition is encountered).

省略析构函数调用本身绝不会导致不确定的行为。但是,尝试在此方面进行任何优化都是毫无意义的,例如模板,因为琐碎的析构函数刚刚被优化。

Omitting destructor calls never per se leads to undefined behavior. However, it's pointless to attempt any optimizations in this area in e.g. templates, since a trivial destructor is just optimized away.

现在,要求是可以复制的,并且类型必须匹配。但是,这可能太严格了。 Dos Reis的N3751 至少提出了不同的建议类型也可以正常工作,我可以想象这条规则将来会扩展到对一种类型进行琐碎的拷贝分配。

Right now, the requirement is being trivially copyable, and the types have to match. However, this may be too strict. Dos Reis's N3751 at least proposes distinct types to work as well, and I could imagine this rule being extended to trivial copy assignment across one type in the future.

但是,您具体显示的内容并没有太多有意义的(特别是因为您要分配给格式错误的标量xvalue),因为琐碎的赋值可以在其赋值实际上不是琐碎的类型之间进行,也就是说,语义与<$相同c $ c> memcpy 。例如。 is_trivially_assignable< int& 并不意味着可以分配一个或多个。

However, what you've specifically shown does not make a lot of sense (not least because you're asking for assignment to a scalar xvalue, which is ill-formed), since trivial assignment can hold between types whose assignment is not actually "trivial", that is, has the same semantics as memcpy. E.g. is_trivially_assignable<int&, double> does not imply that one can be "assigned" to the other by copying the object representation.

这篇关于管理琐碎的类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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