【发布时间】:2019-12-08 15:42:44
【问题描述】:
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>();
}
根据cppref:
变量、函数、模板参数对象的名称(因为 C++20) 或数据成员,无论类型如何,例如 std::cin 或 标准::endl。即使变量的类型是右值引用, 由其名称组成的表达式是左值表达式;
两个问题:
1.为什么vc++ 2019 (with /std:c++latest) 不接受代码?
2。为什么 C++20 允许模板参数对象是左值?
【问题讨论】:
-
它到底应该取什么地址?
N不是变量。 -
即使你可以说服你的编译器采用那个地址(我不知道它是否有意义),增加一个
const值会触发 UB。 -
另外,如果你想要一个标准的答案,我建议使用language-lawyer 标签。
-
也许
++*const_cast<int*>部分可以为了最小的例子而省略?还是应该在这里相关? -
同样来自cppreference: 当一个非类型模板参数的名字用在类模板主体内的表达式中时,它是一个不可修改的纯右值,除非它的类型是左值引用类型,或者除非它的类型是类类型(C++20 起)。。你不能取prvalue的地址。
标签: c++ constants language-lawyer constexpr c++20