为什么std::is_const<const int&>::value的评估结果为false?

7
这是问题如何检查对象是否为const的一个分支。
我很惊讶看到以下程序。
#include <iostream>
#include <type_traits>

int main() 
{
   std::cout << std::boolalpha;
   std::cout << std::is_const<const int&>::value << "\n";
}

生成了以下输出

false

在什么情况下,将const int&视为非const类型是有意义的?


9
is_const<T> 的定义是“T 是带 const 修饰符的”。由于引用无法进行 cv 限定,因此从语言角度来看这是有道理的。 - Mat
请参见https://dev59.com/QVfUa4cB1Zd3GeqPLtjR?rq=1 - MSalters
@Mat,您能否把您的评论转换成答案吗?那似乎包含了最好的答案。 - R Sahu
2个回答

13

或许通过这个例子更容易理解

std::cout << std::is_const<int const *>::value << "\n";  // pointer to const int
std::cout << std::is_const<int * const>::value << "\n";  // const pointer to int

输出:

false
true
第一种类型是指向const int的指针,而在第二种情况中,int *本身是const。因此,前者为false,后者为true。同样地,如果你有一个对const int的引用,如果int& const是有效的,它将导致true

1
由于类型为引用的变量在初始化后不能指向另一个对象,因此std::is_const<int&>::valuestd::is_const<const int&>::value评估为“true”比“false”更有意义。 - R Sahu
@RSahu 我不明白你为什么这样想。正如你所理解的那样,int const& 中的 const 表示 int 不能被修改。is_const 的目的是指示 T 是否带有 const 限定符(引用自 20.10.4.3)。在你列出的两种情况中,T = int&;显然,T 不是 const。在任一情况下返回 true 都是违反直觉的。 - Praetorian
我理解这个。也许我很难证明它的指定行为。对我来说,把引用变量的const性看作是它所引用类型的const性更有意义。 - R Sahu
@RSahu 我能理解你的想法,但你会同意这种“const因为其他选项是不良形式”的行为只适用于引用类型。对于T = U*的情况甚至没有意义。这将是另一个每个人都需要记住的特殊情况。 - Praetorian
是的,我同意。它只适用于引用类型。请理解我从语言用户的角度来说话。从语言开发者的角度来看,is_const的行为可能更有意义。 - R Sahu

0

const 限定符用于引用时,仅表示通过引用无法修改值。但是,它仍然可以通过其他方式进行修改。例如:

int a = 1;
const int &b = a;

std::cout << b << std::endl;  // Prints 1

a = 2;

std::cout << b << std::endl;  // Prints 2

因此,您不能假设 const 引用的值实际上是常量。

2
不知道为什么会有Downvote。它正确地说明了这里的“const”仅适用于涉及“b”的表达式类型。既不是“a”也不是“b”本身是“const”。(话说,Praetorian的答案更清晰) - MSalters
4
这是真的,但与问题无关。 - M.M

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接