为什么vc ++ 2019不接受代码?

xml*_*lmx 3 c++ const language-lawyer constexpr c++20

template<int N>
void f()
{
    constexpr int n = 9;
    ++*const_cast<int*>(&n); // ok
    ++*const_cast<int*>(&N); // error C2101: '&' on constant
}

int main()
{
    f<8>();
}
Run Code Online (Sandbox Code Playgroud)

根据cppref:

变量,函数,模板参数对象(自C ++ 20起)或数据成员的名称,无论类型如何,例如std :: cin或std :: endl。即使变量的类型是右值引用,由其名称组成的表达式也是左值表达式。

两个问题:

1.为什么vc ++ 2019(带有/ std:c ++ latest)不接受代码?

2.为什么C ++ 20允许模板参数对象为左值?

Sto*_*ica 7

模板参数对象是一个规范术语,仅指具有类类型的模板参数。

temp.param / 6(强调我的)

... 命名为类类型T的非类型模板参数的id表达式表示类型为const T的静态存储持续时间对象,称为模板参数对象,其值是经过处理后的相应模板参数的值转换为模板参数的类型。相同类型的程序中具有相同值的所有此类模板参数表示相同的模板参数对象。[?注意:如果id表达式命名为非类型的非引用模板参数,则它具有非类类型的则为prvalue。否则,如果类型为T,则为左值,类型为const T([expr.prim.id.unqual])。-?尾注?]

由于int不是类类型,因此它不是模板参数对象。我们可以在此处查阅有关值类别的规范文本的相关部分,该文本支持以下注释:

expr.prim.id.unqual / 2

...如果实体是函数,变量,结构化绑定([dcl.struct.bind]),数据成员或模板参数对象,则为左值;否则为prvalue。

由于我们不在“模板参数对象”的情况下,因此我们正在处理一个prvalue,因此可能不会&像其他任何prvalue一样对它应用一元。