为什么不能确定const T&是const? [英] Why is `const T&` not sure to be const?
问题描述
template<typename T>
void f(T a, const T& b)
{
++a; // ok
++b; // also ok!
}
template<typename T>
void g(T n)
{
f<T>(n, n);
}
int main()
{
int n{};
g<int&>(n);
}
请注意:b
属于const T&
,++b
可以!
为什么const T&
不确定是常量?
Why is const T&
not sure to be const?
推荐答案
欢迎使用const和引用崩溃.当您拥有const T&
时,引用将应用于T
,const
也是如此.您像这样呼叫g
Welcome to const and reference collapsing. When you have const T&
, the reference gets applied to T
, and so does the const
. You call g
like
g<int&>(n);
,因此您已指定T
为int&
.当我们将引用应用于左值引用时,两个引用会折叠为一个引用,因此int& &
变为int&
.然后我们从 [dcl.ref]/1 中了解规则,其中指出,如果将const
应用于引用,则将其丢弃,因此int& const
变为int&
(请注意,您实际上不能声明int& const
,它必须来自typedef或模板).这意味着
so you have specified that T
is a int&
. When we apply a reference to an lvalue reference, the two references collapse to a single one, so int& &
becomes just int&
. Then we get to the rule from [dcl.ref]/1, which states that if you apply const
to a reference it is discarded, so int& const
just becomes int&
(note that you can't actually declare int& const
, it has to come from a typedef or template). That means for
g<int&>(n);
您实际上是在打电话
void f(int& a, int& b)
您实际上并没有在修改常量.
and you are not actually modifying a constant.
您曾称g
为
g<int>(n);
// or just
g(n);
然后T
将是int
,并且f
将被标记为
then T
would be int
, and f
would have been stamped out as
void f(int a, const int& b)
由于T
不再是引用,因此将const
和&
应用于该引用,并且由于尝试修改常量变量,您将收到一个编译器错误.
Since T
isn't a reference anymore, the const
and the &
get applied to it, and you would have received a compiler error for trying to modify a constant variable.
这篇关于为什么不能确定const T&是const?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!