You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何sizeof(T)在new表达式中被解析为两个参数?如何修复编译错误?

解决 error: no matching function for call to 'operator new' 编译错误

问题原因分析

你遇到的问题核心是对**placement new(定位new)**的语法理解有误。

看你的代码:

new(sizeof(T), tmp) T{std::move(buffer[i])};

你可能误以为需要手动传递sizeof(T)作为内存大小参数,但实际上C++的new表达式(包括placement new)会自动将sizeof(T)作为第一个参数传递给operator new。你把sizeof(T), tmp放进new后的括号里,会被编译器解析成两个独立的placement参数,最终尝试调用的是:

operator new(sizeof(T), sizeof(T), tmp);

而标准库中只提供了最常用的placement new重载:

void* operator new(std::size_t, void*) noexcept;

它只接受两个参数:第一个是自动传递的大小,第二个是目标内存的指针。你的代码传递了三个参数(自动的size_t + 手动的sizeof(T) + tmp),即便tmp能隐式转为void*,参数数量也不匹配,所以编译器找不到对应的重载,报出了"no matching function"的错误。

你猜测的“sizeof(T)被解析为sizetype和T两个参数”并不准确,真实原因是逗号表达式在这里被当成了多个placement参数,加上编译器自动添加的size_t参数,导致参数列表完全不匹配标准库的函数签名。

修复方法

既然你的目标是在tmp指向的内存区域构造T对象,只需要去掉手动传递的sizeof(T),正确的placement new写法如下:

new (tmp) T{std::move(buffer[i])};

这样编译器会自动调用标准的placement new重载:operator new(sizeof(T), tmp),其中tmp会被隐式转换为void*,完全符合标准库的函数签名,编译就能通过了。

额外提醒:使用placement new构造对象后,你需要手动调用析构函数(tmp->~T();)来销毁对象,因为placement new不会自动释放内存(这块内存是你自己管理的)。


内容的提问来源于stack exchange,提问作者ElJay

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:53:11