展示位置的返回值new [英] Return value of placement new

查看:139
本文介绍了展示位置的返回值new的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑以下C ++ 14代码:

Consider the following C++14 code:

#include <cassert>
#include <new>
#include <type_traits>

struct NonStandardLayout
{
    // ...
};

int main()
{
    using T = NonStandardLayout;

    std::aligned_storage_t< sizeof(T), alignof(T) > storage;
    T *const valid_ptr = new(static_cast<void *>(&storage)) T;

    T *const maybe_ptr = reinterpret_cast<T *>(&storage);
    assert(maybe_ptr == valid_ptr); // ???

    valid_ptr->T::~T();
    return 0;
}

是否通过标准保证示例中的断言对于任何类型T都不会失败?

Is it guaranteed by the standard that the assert in the example will never fail, for any type T?

查找最新标准( http://eel.is/c++draft/),我看不到对此特定情况的任何引用,但是我发现以下段落可以说是答案为是".

Looking in the latest standard (http://eel.is/c++draft/), I cannot see any reference to this particular scenario but I have found the following paragraphs that arguably points to the answer 'yes'.

以为我认为是对的吗 [expr.new/15] 和 [new.delete.placement/2] 一起声明valid_ptr的值将始终等于storage的地址?

Is it correct of me to think that [expr.new/15] and [new.delete.placement/2] together states that the value of valid_ptr will equal the address of storage, always?

如果是,reinterpret_cast是否会产生一个指向完全构造的对象的指针,这是真的吗?因为, [expr.reinterpret.cast/7], [expr.static.cast/13] 和 [basic.compound/4] 在一起似乎表明情况应该如此.

If so, is it true that the reinterpret_cast will yield a pointer to a fully constructed object? Because, [expr.reinterpret.cast/7], [expr.static.cast/13] and [basic.compound/4] together seem to indicate that it should be the case.

根据我的观察,默认分配器的库实现似乎与此类似,不必担心!像这样进行投射真的安全吗?

From my observations, library implementations of the default allocator seem to cast similar to this and without worry! Is it really safe to cast like this?

我们如何确定两个指针相同,还是可以?

How can we be sure that the two pointers will be the same, or can we?

推荐答案

我很惊讶,没有人提到这个廉价的反例:

I'm surprised no one has mentioned this cheap counterexample yet:

struct foo {
  static foo f;
  // might seem dubious but doesn't violate anything
  void* operator new(size_t, void* p) {return &f;}
};

在Coliru上进行演示.

但是,除非调用特定于类的放置版本,否则您的断言应该成立.这两个表达式都必须表示与另一个答案中说明的地址相同的地址(要点是,标准的非分配operator new只是返回指针参数,而新表达式不做任何花哨的操作),而且这两个都不是指针越过某个对象的末尾,因此它们以[expr.eq]/2相等.

Unless a class-specific placement version is called, however, your assertion should hold. Both expressions have to represent the same address as explained in the other answer (the main point being that the standard non-allocating operator new simply returns the pointer argument and the new expression not doing anything fancy), and neither of these is a pointer past the end of some object so, by [expr.eq]/2, they compare equal.

这篇关于展示位置的返回值new的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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