升级到 C++ 20 时对运算符 new[] 的调用不明确

问题描述 投票:0回答:1

使用 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 版本。

c++ templates visual-c++ c++20 new-operator
1个回答
0
投票

这看起来像是一个编译器错误。

new T
的实例化中,分配的类型是
T
并且是数组类型。因此,只应查找
operator new[]
来查找 new 表达式的分配函数。自第一个 C++ 标准以来就是这种情况,现在仍然如此。因此,
void *operator new(size_t)
甚至不应该成为在所谓的不明确的重载决议中考虑的候选者。

但是代码确实有未定义的行为,请参阅问题下的我的评论。

© www.soinside.com 2019 - 2024. All rights reserved.