60
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&不确定是const?

4

2 回答 2

66

欢迎使用 const 和参考折叠。当您拥有const T&时,引用将应用于Tconst. 你打电话g喜欢

g<int&>(n);

所以你已经指定这T是一个int&. 当我们对一个左值引用应用一个引用时,这两个引用折叠成一个引用,所以int& &变成了 just int&。然后我们从[dcl.ref]/1得到规则,它指出如果你应用const到一个引用,它会被丢弃,所以int& const就变成了int&(注意你实际上不能声明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并且&get 应用于它,并且您会收到编译器错误以尝试修改常量变量。

于 2019-02-01T13:36:51.907 回答
-3

我知道已经有一个公认的答案是正确的,但只是添加一点,即使在模板领域之外并且通常只是在函数声明中......

( const T& ) 

不一样

( const T )

在与第一个匹配的示例中,您有一个 const 引用。如果您确实想要一个不可修改的 const 值,请删除第二个示例中的引用。

于 2019-02-01T14:17:23.367 回答