C++ 如何分配一个适合容纳T型对象的缓冲区(可能是过度对齐的,可能有新的运算符等)

C++ 如何分配一个适合容纳T型对象的缓冲区(可能是过度对齐的,可能有新的运算符等),c++,language-lawyer,C++,Language Lawyer,在我正在处理的库中,我需要分配最终将传递给placement-new的空间来构造任意类型的对象。这些实例将返回给调用者代码,并且需要在用户只编写delete t时正常工作或拥有他们正在使用的任何独特的\u ptr模拟为他们做这件事 T*T=newchar[sizeof(T)]的简单方法至少有几个问题,我已经注意到了: 如果T是用alignas说明符声明的,那么我不能相应地手动填充缓冲区,因为生成的地址不是传递给delete 表达式删除t将是operator delete()和operator d

在我正在处理的库中,我需要分配最终将传递给placement-
new
的空间来构造任意类型的对象。这些实例将返回给调用者代码,并且需要在用户只编写
delete t时正常工作或拥有他们正在使用的任何
独特的\u ptr
模拟为他们做这件事

T*T=newchar[sizeof(T)]
的简单方法至少有几个问题,我已经注意到了:

  • 如果
    T
    是用
    alignas
    说明符声明的,那么我不能相应地手动填充缓冲区,因为生成的地址不是传递给
    delete
  • 表达式
    删除t将是
    operator delete()
    operator delete[]()
  • 如果代码声明了一个自定义的
    T::operator new
    T::operator delete
    (用于内存池、隔离、跟踪等),那么我们会忽略调用分配器,并且在调用反分配器时会错配
  • 看起来更好的是
    T*T=std::allocator::allocate(1)
    ,它解决了点1中的对齐问题和点2中的标量/数组不匹配问题。但是,根据,它总是调用全局
    ::操作符new
    。因此,它仍然会在第3点失败


    引用错误吗?在我缺少的标准库中,是否有一些稍微高级的例程做正确的事情?是否有一些技巧可以在不使用讨厌的模板代码的情况下正确执行正确的操作,以检查是否存在
    T::operator new

    我认为您希望遵循a用于确定正确调用的相同规则,但我不知道有什么方法可以自动生成该调用。原则上(我认为)编写通常的模板家族来检测特定于类的重载是否存在,以及
    alignof(T)>\uuu STDCPP\u DEFAULT\u NEW\u ALIGNMENT\uuuu的分支在原则上是相当简单的,但我同意这很繁琐。

    我认为您需要遵循a用于确定正确调用的相同规则,但我不知道有什么办法可以自动发出那个电话。原则上(我认为)编写通常的模板家族来检测特定于类的重载是否存在,以及
    alignof(T)>\uuuu STDCPP\u DEFAULT\u NEW\u ALIGNMENT\uuuu
    的分支是否存在,这是相当简单的,但我同意这很繁琐。

    您可能需要检查
    std::vector
    的实现如何处理它。它应该有完全相同的问题。看起来libc++没有尝试,而微软的实现拒绝了:内置的
    new
    处理程序调用
    ::operator new
    ,它生成的内存保证可以针对任何情况进行对齐type@M.M当然可以,但我不能直接给新t打电话,因为我有一些约束条件来构造对象,而不是分配对象将居住的空间。@Philler我的注释适用于
    new char[]
    您可能需要检查
    std::vector
    的实现如何处理它。它应该有完全相同的问题。看起来libc++没有尝试,而微软的实现拒绝了:内置的
    new
    处理程序调用
    ::operator new
    ,它生成的内存保证可以针对任何情况进行对齐type@M.M当然可以,但我不能直接给新t打电话,因为我有一些约束条件来分别构造对象和分配它将居住的空间。@Philler我的注释适用于
    newchar[]