为什么`const T&`不确定是const?

时间:2019-02-01 13:32:34

标签: c++ templates const function-templates const-reference

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&不确定是常量?

2 个答案:

答案 0 :(得分:65)

欢迎使用const和reference collapsing。当您拥有const T&时,引用将应用于Tconst也是如此。您像这样致电g

g<int&>(n);

因此您已指定Tint&。当我们将引用应用于左值引用时,两个引用会折叠为一个引用,因此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值,请像第二个示例中一样删除引用。