代码之家  ›  专栏  ›  技术社区  ›  Fureeish

为什么一个新的表达式可以正确地生成指针类型,即使它应该返回void*?[副本]

  •  6
  • Fureeish  · 技术社区  · 5 年前

    我们知道 void* 不包含有关它指向的实际数据类型的信息。但是,从cppreference开始 new and new[] 我们知道那些接线员回来了 空的* . 那么,假设:

    auto x = new int{};
    

    知道 新的 操作员应返回 空的* , x 被推断为 int* ,不是 无效* ?

    再举一个例子:

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

    我们再加一些 T型 类型 显示层:

    template <typename T>
    struct TD;
    

    测试代码:

    int main() {
        auto x = new foo{};
    
        TD<decltype(x)>{};
    }
    

    代码无法编译,错误表明 decltype(x) foo* . 如果我们把最后一行注释掉 main ,我们会知道, 空的* -返回运算符将被调用,因为 new called! 正在打印。

    1 回复  |  直到 5 年前
        1
  •  7
  •   Pete Becker    5 年前

    很容易混淆 new 带运算符的关键字 新的 ,但它们是两种不同的东西。当您编写内存分配函数时,它的名称是 operator new 正如你所说,它确实回来了 void* . 但通常不直接调用该运算符;而是使用 新的 关键字。这个 编译程序 理解那个关键字;它调用 新操作员 获取对象(或对象,数组)的内存 新的 )正在创建它,并执行任何适当的初始化。该表达式的结果类型是指向所创建类型的指针。

    所以,在密码里

    auto x = new int{};
    

    表达式的类型 new int{} int* ,因此 x 也是 内景* .