为什么 `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&
不确定是const?
欢迎使用 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
和 &
应用到它,你会收到一个编译器错误试图修改常量变量。
我知道已经有一个被接受的答案是正确的,但只是补充一点,即使在模板领域之外,也只是在一般的函数声明中...
( const T& )
与
不一样
( const T )
在您匹配第一个的示例中,您有一个 const 引用。如果您真的想要一个不可修改的 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&
不确定是const?
欢迎使用 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
和 &
应用到它,你会收到一个编译器错误试图修改常量变量。
我知道已经有一个被接受的答案是正确的,但只是补充一点,即使在模板领域之外,也只是在一般的函数声明中...
( const T& )
与
不一样( const T )
在您匹配第一个的示例中,您有一个 const 引用。如果您真的想要一个不可修改的 const 值,请删除第二个示例中的引用。