为什么将函数指针指向 `operator new` 在 C++14 中可以编译,但在 C++17 中却不能编译?

Vin*_*abo 13 c++ operator-overloading auto c++14 c++17

考虑以下代码(godbolt 链接):

#include <cstdio>

int main() {
    auto foo = operator new;
    void* mem = foo(1);
    printf("%p", mem);
}
Run Code Online (Sandbox Code Playgroud)

此代码在 GCC、Clang 和 MSVC 上编译,C++ 版本设置为 C++ 14,但在使用 C++ 17 或更高版本时无法编译。在 GCC 上,它失败并出现以下错误:

error: unable to deduce 'auto' from 'operator new'
Run Code Online (Sandbox Code Playgroud)

我预计代码在两个版本中要么编译,要么不编译。C++ 17 中发生了什么变化使得operator new不再能够推断出 的类型?

YSC*_*YSC 15

C++ 17 中发生了什么变化,导致无法再推导 new 运算符的类型?

这是P0035R4 1。它在 C++17 中引入了一个新的(双关语)operator new,允许对过度对齐的数据进行动态内存分配

您可以在cppreference.com上找到以下两个运算符:

void* operator new  ( std::size_t count );
void* operator new  ( std::size_t count, std::align_val_t al );
Run Code Online (Sandbox Code Playgroud)

这会产生auto foo = operator new歧义,因为它可以匹配两个运算符。

正如用户nm 将在 Reddit 上看到的那样

operator new不是可寻址的库函数,因此该程序具有未指定的行为,并且在任何 C++ 标准中都可能格式错误。


1)

问题陈述

为了编纂广泛的现有实践,C++11 添加了为类类型指定增强对齐(也称为过度对齐)的功能。不幸的是(但也与现有实践一致),C++11 没有指定任何可以动态正确分配过度对齐数据的机制(即尊重数据的对齐方式)。例如:

class alignas(16) float4 {
  float f[4];
};
float4 *p = new float4[1000];
Run Code Online (Sandbox Code Playgroud)

在此示例中,C++ 的实现不仅不需要为数组分配正确对齐的内存,而且出于实际目的,几乎需要错误地进行分配。无论如何,肯定需要通过不考虑指定对齐值的进程来执行分配。

这代表了语言中对对齐的支持存在一个漏洞,确实需要填补。