使用 msvc 从 C++17 升级到 C++20 后编译以下代码时出现错误:
#include <tuple>
template <typename T>
void alloc(void* dest)
{
using ty = decltype(new T);
reinterpret_cast<ty&>(dest) = new T;
}
int main()
{
int obj[5][10];
alloc<decltype(obj)>(obj);
return 0;
}
错误是:
<source>(7): error C2668: 'operator new[]': ambiguous call to overloaded function
predefined C++ types (compiler internal)(58): note: could be 'void *operator new[](size_t)'
predefined C++ types (compiler internal)(33): note: or 'void *operator new(size_t)'
<source>(7): note: while trying to match the argument list '(unsigned __int64)'
<source>(13): note: see reference to function template instantiation 'void alloc<int[5][10]>(void *)' being compiled
(这是一个最小的重现,当我删除元组包含时,它会编译,但是我不能只删除实际代码中的包含)。
使用 C++ 见解,我可以看到 c++ 17 正在执行我所期望的操作,模板替换生成了
new int[5UL][10];
为 new T
。
我不确定为什么这在 C++ 20 中现在不明确,以及如何指定我需要的 new 版本。
这看起来像是一个编译器错误。
在
new T
的实例化中,分配的类型是 T
并且是数组类型。因此,只应查找 operator new[]
来查找 new 表达式的分配函数。自第一个 C++ 标准以来就是这种情况,现在仍然如此。因此,void *operator new(size_t)
甚至不应该成为在所谓的不明确的重载决议中考虑的候选者。
但是代码确实有未定义的行为,请参阅问题下的我的评论。