为什么 new 表达式可以正确生成指针类型,即使它应该返回 void*?

Fur*_*ish 7 c++ void-pointers language-lawyer new-expression

我们知道它void*没有关于它指向的数据的实际类型的信息。但是,从 cppreference 开始newnew[]我们知道这些运算符返回void*. 那么,如何给出:

auto x = new int{};
Run Code Online (Sandbox Code Playgroud)

知道new操作符应该返回void*x被推导为一种类型int*,不是void*吗?

再考虑一个例子:

struct foo {
    static void* operator new(std::size_t n) {
        std::cout << "new called!\n";
        return ::new char[n];
    }
};
Run Code Online (Sandbox Code Playgroud)

让我们添加一些牛逼YPE d isplayer:

template <typename T>
struct TD;
Run Code Online (Sandbox Code Playgroud)

和测试代码:

int main() {
    auto x = new foo{};

    TD<decltype(x)>{};
}
Run Code Online (Sandbox Code Playgroud)

代码无法编译,错误指示decltype(x)foo*。如果我们注释掉 的最后一行main,我们就会知道我们的void*-returning 操作符会因为new called!被打印而被调用。

Pet*_*ker 8

很容易将new关键字与 operator混淆new,但它们是两种不同的东西。当你编写一个内存分配函数时,它的名字是operator new,正如你所说,它确实是 return void*。但是您通常不会直接调用该操作员;相反,您使用new关键字创建一个新对象。所述编译器理解关键字; 它调用operator newnew正在创建的对象(或对象,用于数组)获取内存,并进行任何适当的初始化。该表达式的结果类型是指向正在创建的类型的指针。

所以,在代码中

auto x = new int{};
Run Code Online (Sandbox Code Playgroud)

表达式的类型new int{}int*,所以推导出的类型x也是int*