MSVC 拒绝编译此代码是否正确?

Is MSVC correct in refusing to compile this code?

考虑这段代码 (godbolt):

#include <type_traits>
#include <memory>
#include <cstdlib>

using namespace std;

template<auto L, class T = decltype(L)>
using constant = integral_constant<T, L>;

int main() 
{
    unique_ptr<void, constant<&free>> p1;
    unique_ptr<void, constant<free>> p2;    // <-- MSVC refuses to compile this line
    return 0;
}

为什么 MSVC 拒绝编译突出显示的行?此代码有效吗?

MSVC 产生:

<source>(13): error C2975: 'L': invalid template argument for 'constant', expected compile-time constant expression
<source>(7): note: see declaration of 'L'

Pre-C++20 它看起来像一个 MSVC 错误。

C++20 之后,the behavior is unspecified(感谢@heapunderrun) 因为 free 不在允许获取地址的函数列表中。但我认为它仍然是一个错误(即使符合要求),因为如果您使用 &.

,MSVC 允许您获取相同函数的地址

在这种情况下,模板参数推导就好像由 constexpr auto x = free; ([temp.arg.nontype]/1) 完成,并且上述声明被 MSVC 接受,推导一个函数指针。

传递模板参数时禁止某些隐式转换,允许的转换在 [expr.const]/10 中列出并包括“function-to-pointer 转换”。