Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the vc++ 2019 not accept the code?

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>();
}

According to cppref:

the name of a variable, a function, a template parameter object (since C++20), or a data member, regardless of type, such as std::cin or std::endl. Even if the variable's type is rvalue reference, the expression consisting of its name is an lvalue expression;

Two questions:

1. Why does vc++ 2019 (with /std:c++latest) not accept the code?

2. Why does C++20 permit a template parameter object be an lvalue?

like image 642
xmllmx Avatar asked Feb 07 '26 09:02

xmllmx


1 Answers

template parameter object is a normative term, that refers only to template parameters that have a class type.

temp.param/6 (emphasis mine)

...An id-expression naming a non-type template-parameter of class type T denotes a static storage duration object of type const T, known as a template parameter object, whose value is that of the corresponding template argument after it has been converted to the type of the template-parameter. All such template parameters in the program of the same type with the same value denote the same template parameter object. [ Note: If an id-expression names a non-type non-reference template-parameter, then it is a prvalue if it has non-class type. Otherwise, if it is of class type T, it is an lvalue and has type const T ([expr.prim.id.unqual]). — end note ]

Since int is not of a class type, it's not a template parameter object. We can consult the relevant section for the normative text on the value category here, which supports the note:

expr.prim.id.unqual/2

... The expression is an lvalue if the entity is a function, variable, structured binding ([dcl.struct.bind]), data member, or template parameter object and a prvalue otherwise ...

Since we are not in the "template parameter object" case, we are dealing with a prvalue, and as such may not apply unary & to it, like any other prvalue.

like image 175
StoryTeller - Unslander Monica Avatar answered Feb 09 '26 00:02

StoryTeller - Unslander Monica