C++ 为什么语言中内置了非放置“new”和“delete”,而不仅仅是常规函数?

C++ 为什么语言中内置了非放置“new”和“delete”,而不仅仅是常规函数?,c++,new-operator,delete-operator,C++,New Operator,Delete Operator,为什么非放置和语言实现为内置的而不是常规的函数 如果我们有 向操作系统请求/返回内存的一种方法 显式调用构造函数的一种方法(placementnew) 显式调用析构函数的一种方法(~T()) …为什么不放置new和delete不能成为标准库中的常规函数?例如: template <typename T, typename... Ts> T* library_new(Ts&&... xs) { auto* ptr = /* request enough me

为什么非放置和语言实现为内置的而不是常规的函数

如果我们有

  • 向操作系统请求/返回内存的一种方法

  • 显式调用构造函数的一种方法(placement
    new

  • 显式调用析构函数的一种方法(
    ~T()

…为什么不放置
new
delete
不能成为标准库中的常规函数?例如:

template <typename T, typename... Ts>
T* library_new(Ts&&... xs)
{
    auto* ptr = /* request enough memory for `T` from OS */;
    new (ptr) T(std::forward<Ts>(xs)...);
    return ptr;
}

template <typename T>
void library_delete(T* ptr)
{
    ptr->~T();
    /* reclaim memory for `T` from OS */
} 
模板
新图书馆(Ts&&…xs)
{
auto*ptr=/*从OS*/请求足够的内存用于'T';
新(ptr)T(标准:正向(xs)…);
返回ptr;
}
模板
无效库_删除(T*ptr)
{
ptr->~T();
/*从操作系统中回收'T'的内存*/
} 

如果它们已经作为独立功能提供,那么就不可能为它们提供用户定义的替换

e、 g.现在根据标准,我需要编写自己的globl
new
delete
它们将在程序之外使用

18.6.2存储分配和解除分配[新建.删除]

2可替换:C++程序可以使用这些函数签名中的任何一个来定义函数,从而替换C++标准库定义的默认版本


如果这些函数与其他库函数一样提供,则每次对
new
delete
的正常调用都会导致“多个重载函数实例匹配参数”错误。

如果用户的目标是在某个内存位置创建对象,然后,
new
似乎是一种自然的方法,因为转发引用可变模板放置新的在那些日子已经不是什么事情了。正如模板正确指出的那样,模板于1990年发布,新的布局于1989年发布。另一方面,可变模板,仅在C++ 11中成为C++的一部分。
tl;dr无法将一组参数转发给任意类型的构造函数(就像现在使用
make
函数所做的那样)。

也许这不是最好的参考,但这是维基百科在C++中所说的:

在C++的早期版本中,没有新的布局;相反,开发人员在构造函数中使用显式赋值来实现类似的效果。这种做法后来被弃用并废除,第三版的“C++编程语言”并没有提到这种技术。大约在1995年,编译器中增加了对放置新操作符的支持

也许在2017年,可以将
新建
作为标准库函数来实现。您建议的实现使用最近添加的语言功能(其中许多是在2010年之后添加的)

< C++语言,但更古老(1983),在开始时没有任何可变模板,没有<代码>类型名称<代码>,没有放置<代码>新< /C>,没有转发引用。p>
一开始只有常规的
new
,当时它必须是一种语言功能,因为没有办法将其作为库函数来实现。

因为非放置
new
delete
从一开始就使用该语言,放置版本后来才添加?@ThomasRussell theOP的问题是,为什么非placement
new
不是作为使用placement
new
实现的函数提供的@axiac我认为这与好奇同样值得回答。@VittorioRomeo我认为多态性在这里没有任何关联。我认为这纯粹是一种方便的方式来完成您的库函数在当时所做的工作。我将此标记为重复,因为它与另一个问题的答案完全相同:。这个问题中提到的“图书馆替代品”有点滑稽,因为它们是不合时宜的。当C++语言被引入,并且<代码>新的< /代码> /代码>删除< /代码>操作符被创建时,绝对没有办法写下你在这里写的东西!您需要编译器提供“魔力”。为什么不可能?只需通过“用户定义的替换”提供OPs模板的自定义专门化,我是指完全隐藏内置实现的全局替换,而不是某些专门化。@MartinBonner然后再次强调,如果不面对“重载函数的多个实例与参数匹配”错误。基本上是当前的“可替换默认实现”“只是一个解决此类错误的方法。”马丁伯纳,我猜你是在说让这个代码>记忆-分配器[/Cuff]函数是一个弱符号来允许这种行为,对吧?“马丁博纳弱符号是毫无疑问的,因为它们甚至不是C++的一部分。您能指定一些其他方式来实现严格遵守C++标准边界的行为吗?我什么都不知道。最后一段很重要,我认为你应该把它作为第一段。“历史意外:在C++的原始版本中,没有办法编写<代码>新< /代码>作为库函数。一旦代码>新< /Cord>是关键字,删除>代码>似乎也需要。”@ MartinBonner感谢这个建议,但我认为它是好的。如果没有第二段,最后一段可能不清楚。他们可能会问:“为什么没有好的方法?确实有,请参见
make\u tuple
例如“变量模板…”。。。为了返回正确的类型(而不是
void*
),您需要普通的ol'模板,这是我们当时没有的。是的,
new
的全部要点是它返回了正确类型的随时可用指针,无需从
void*
强制转换。没有模板,就不是po