这是代码:
int main()
{
int* p = nullptr;
const int* cp = p;
const int*& ref = cp;
const int*& ref0 = cp;
const int*& ref1 = p;//not allowed
const int*& ref2 = static_cast<const int*&>(p);//not allowed
int* const & ref3 = p;//allowed. Why?
return 0;
}
当我运行它时,我得到了
test.cpp:7:14: error: non-const lvalue reference to type 'const int *' cannot
bind to a value of unrelated type 'int *'
const int*& ref1 = p;
^ ~
test.cpp:8:21: error: non-const lvalue reference to type 'const int *' cannot
bind to a value of unrelated type 'int *'
const int*& ref2 = static_cast<const int*&>(p);
我很难理解为什么。也许const
在这里发挥作用。当我写const int*&
或int* const &
时,我不知道const
适用于指针或引用。const int* const &
也让我感到困惑。 我想知道以下项目的语法:
对 const 指针的引用。
对指向常量的指针的引用。
对常量指针的引用,该指针指向常量。
和常量参考版本:
对指针的常量引用。
对常量指针的常量引用。
对指向常量的指针的常量引用。
对常量指针的常量引用,该指针是常量并指向常量。
很抱歉我的困惑。
您的p
是指向int
的指针。const int*&
是对指向const
int
的指针的引用。由于p
是int
而不是const
int
,因此不能将应该引用指向const
int
指针的引用绑定到引用p
。
阅读C++声明的关键是"从内到外"阅读它们,即从标识符(名称)开始,然后找出出路。举个例子:
int* const & ref3;
是对指向int
的const
指针的引用。我们从标识符(ref3
)开始,然后向外工作。我们发现的第一件事是&
.所以ref3
是一个参考。接下来是const
,所以无论ref3
指的是什么,都是const
的东西。接下来是一个*
,所以引用所指const
的东西是一个指针。最后int
,我们正在处理对const
指针的引用int
。
请注意,标识符的两端都可能发生一些事情。在"解决你的出路"时,你必须考虑哪些说明符/运算符首先绑定/更强烈地绑定,以确定声明的类型。例如:
int const * a[10];
同样,我们从标识符开始a
.[]
比*
结合更强烈,所以a
是一个由10个元素组成的数组。a
是一个数组的这些元素是什么?接下来是*
,所以a
是一个由10个指针组成的数组。最后,我们发现a
是一个包含 10 个指向const
int
的指针的数组。请注意,如果最后还剩下孤独的const
,那么const
就会与之前的一切绑定。这就是允许我们也写const int a
的原因,这相当于int const a
.
还可以使用括号来影响运算符在声明中生效的顺序。例如
int const (* a)[10];
将是指向 10 个const
int
数组的指针,而不是指向const
int
的 10 个指针的数组。