为什么 new 表达式可以正确地生成指针类型,即使它应该 return void*?
How come a new-expression can correctly produce the pointer type, even though it should return void*?
我们知道 void*
没有关于它指向的数据的实际类型的信息。但是,从 new
and new[]
上的 cppreference 我们知道那些运算符 return void*
。那么,怎么会给出:
auto x = new int{};
知道 new
运算符应该 return void*
,x
被推断为 int*
类型,而不是 void*
?
考虑另一个例子:
struct foo {
static void* operator new(std::size_t n) {
std::cout << "new called!\n";
return ::new char[n];
}
};
让我们添加一些 TypeDisplayer:
template <typename T>
struct TD;
和测试代码:
int main() {
auto x = new foo{};
TD<decltype(x)>{};
}
代码编译失败,错误表明 decltype(x)
是 foo*
。如果我们注释掉 main
的最后一行,我们将知道我们的 void*
-returning 运算符将由于 new called!
被打印而被调用。
很容易将 new
关键字与运算符 new
混淆,但它们是两个不同的东西。当您编写一个内存分配函数时,它的名称是 operator new
,正如您所说,它确实是 return void*
。但是您通常不会直接致电该接线员;相反,您使用 new
关键字创建一个新对象。 编译器 理解该关键字;它调用 operator new
为正在创建的对象(或数组 new
的对象)获取内存,并执行任何适当的初始化。该表达式的结果类型是指向正在创建的类型的指针。
所以,在代码中
auto x = new int{};
表达式new int{}
的类型是int*
,所以x
的推导类型也是int*
。
我们知道 void*
没有关于它指向的数据的实际类型的信息。但是,从 new
and new[]
上的 cppreference 我们知道那些运算符 return void*
。那么,怎么会给出:
auto x = new int{};
知道 new
运算符应该 return void*
,x
被推断为 int*
类型,而不是 void*
?
考虑另一个例子:
struct foo {
static void* operator new(std::size_t n) {
std::cout << "new called!\n";
return ::new char[n];
}
};
让我们添加一些 TypeDisplayer:
template <typename T>
struct TD;
和测试代码:
int main() {
auto x = new foo{};
TD<decltype(x)>{};
}
代码编译失败,错误表明 decltype(x)
是 foo*
。如果我们注释掉 main
的最后一行,我们将知道我们的 void*
-returning 运算符将由于 new called!
被打印而被调用。
很容易将 new
关键字与运算符 new
混淆,但它们是两个不同的东西。当您编写一个内存分配函数时,它的名称是 operator new
,正如您所说,它确实是 return void*
。但是您通常不会直接致电该接线员;相反,您使用 new
关键字创建一个新对象。 编译器 理解该关键字;它调用 operator new
为正在创建的对象(或数组 new
的对象)获取内存,并执行任何适当的初始化。该表达式的结果类型是指向正在创建的类型的指针。
所以,在代码中
auto x = new int{};
表达式new int{}
的类型是int*
,所以x
的推导类型也是int*
。