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&
不确定是常量?
答案 0 :(得分:65)
欢迎使用const和reference collapsing。当您拥有const T&
时,引用将应用于T
,const
也是如此。您像这样致电g
g<int&>(n);
因此您已指定T
为int&
。当我们将引用应用于左值引用时,两个引用会折叠为一个引用,因此int& &
变成int&
。然后,我们从[dcl.ref]/1转到规则,该规则指出,如果将const
应用于引用,则它将被丢弃,因此int& const
变成int&
(请注意,您可以t实际上声明int& const
,它必须来自typedef或模板。这意味着
g<int&>(n);
您实际上是在打电话
void f(int& a, int& b)
您实际上并没有在修改常量。
您曾称g
为
g<int>(n);
// or just
g(n);
然后,T
将是int
,并且f
将被标记为
void f(int a, const int& b)
由于T
不再是引用,因此const
和&
会被应用到它,并且您会因为尝试修改常量变量而收到编译器错误。
答案 1 :(得分:-3)
我知道已经有一个正确的答案,但是只是在模板范围之外,或者只是在函数声明中添加一点点……
( const T& )
与
不同( const T )
在与第一个匹配的示例中,您有一个const引用。如果您确实想要不可修改的const值,请像第二个示例中一样删除引用。