为什么在没有标题的情况下无法识别新的关键字/运算符/函数?
在下面的:
int main()
{
new int; // Works
int* pmem = 0;
new (pmem) int;// Doesn't recognize new keyword/operator/function???
}
在这种情况下,如果不包含 <iostream> 标头,它将无法识别“新”。这是为什么?为什么“新”不需要标题,但放置新需要?如果 'new' 需要定义一个函数,那么为什么 'int* a = new int;' 工作?由于它没有在任何地方定义,我认为它是语言的一部分。然而 'new (&int) int;' 'placement new' 不是语言的一部分吗?
Visual Studio 给出错误:
回答
Placement new 不仅仅用于“无操作”分配。这是为new超出对象大小提供额外参数的通用术语。一个标准的例子是std::nothrow.
由于我们提供参数,编译器必须进行重载解析以选择合适的operator new函数。这意味着必须事先声明重载。最基本的重载是隐式声明的(以某种方式),而void* operator new(std::size_t, void* ptr) noexcept(执行此“分配”的标准库函数)则不是。因此,我们必须包含标题 ( <new>*) 以进行重载解析。
那是 30 年前的设计选择。它本来可以由另一个内置来完成,但是由于将对象放入预先涂好的原始存储中被认为是一项非常高级的功能(与简单的动态分配相反),因此添加库依赖项可能看起来并没有太大的障碍.
* - 你看到了<iostream>影响行为,因为它可能<new>直接或间接地包括。这是允许的,但不是必需的行为。
- `new T` 是一个表达式。它的部分评估涉及调用函数(`operator new`)。这总是正确的。不直观的一点是始终隐式声明一个函数。这是因为简单的动态分配是许多程序中使用的非常基本的东西。`new` 表达式的其他形式需要显式声明。