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

标签 c++ templates visual-c++ c++20 new-operator

使用 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 T 生成了 new int[5UL][10];

我不确定为什么这在 C++ 20 中现在不明确,以及如何指定我需要的 new 版本。

最佳答案

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

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

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

关于c++ - 升级到 C++ 20 时对运算符 new[] 的调用不明确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/76796033/

相关文章:

c++ - 错误 C2512 : 'std::basic_ostream<_Elem,_Traits>' : no appropriate default constructor available with Visual Studio only

c++ - 为什么 Visual Studio 2013 对此类成员 decltype 有问题?

c++ - OgreSdk 1.9.1 - 断言失败

c++ - 如何翻转 QCheckBox 显示

c++ - 如何为子类定义通用模板化创建函数

c++ - 模板和派生类定义 : error: 'myClass' is not a class, 命名空间,或枚举

c++ - VC++ Winforms 自动生成的项目无法调试 VS2010 : "This Project is out of Date"

c++ - 模板特化/初始化和命名空间?

c++,在QTableWidget中仅插入数字( double )

wpf - 通过 XAML 代码居中 WPF RibbonWindow 标题