好的,所以我正在阅读C ++ Primer,Fifth Editon和我第一次学习constexpr。首先说:
重要的是要理解当我们在a中定义指针时 constexpr声明,constexpr说明符适用于指针, 不是指针指向的类型:
const int *p = nullptr; // p is a pointer to a const
*q = nullptr; // q is a const pointer to int
好吧,我想我自己......好吧,它是一个指向const的指针然后它意味着p(指针)it-self不是常数,所以我可以改变它。所以当然,我在我的IDE上试了一下:
#include <iostream>
#include <list>
#include <vector>
#include <string>
int main()
{
const int x = 0;
const int y = 30;
const int *p = x;
*p = &y;
return 0;
}
猜猜是什么。当我尝试将* p分配给常数y的地址时,它给了我一个错误。那么错误具体
error: assignment of read-only location '* p'|
哇我很惊讶。我真的以为这本书说p是指向const的指针。所以我认为p不是一个恒定的自我,所以你可以改变它。或者我的厌恶是错误的吗?
然后它告诉我:
constexpr int *q = nullptr; // q is a const pointer to int
如果我以前的anaology是正确的那么,这个指针实际上是const-self。所以它可能不会改变..?或者我还是错了吗?
好的伙计,所以我明白了。当我指定指向“对象”或任何东西的指针时,我不应该退缩。但是,当我第一次尝试constexpr时,我得到了这个错误!
error: invalid conversion from 'const int*' to 'int*' [-fpermissive]|
这是我的代码:
int main()
{
const int a = 0;
const int i = 5;
constexpr int *w = &a;
return 0;
}
答案 0 :(得分:4)
你有一个错字。当您*p
取消引用指针时,您可以访问无法更改的基础const int
。
p = &y;
另一方面改变p
指向的内容。具体而言,它会将p
更改为指向合法的y
。
int main()
{
const int x = 0;
const int y = 30;
const int *p = &x;
std::cout << *p << "\n";
p = &y;
std::cout << *p;
return 0;
}
输出:
0
30
我也不得不改变
const int *p = x;
到
const int *p = &x;
否则您尝试使用x
的值初始化指针,而不是x
的地址。
您constexpr
错误与指针类型和您要指向的内容有关。
constexpr int *w = &a;
说给我int *
并指出a
并将其设为constexpr
。现在a
是const int
而非int
尝试这样做会删除const
a
这是非法的。
如果我们将其更改为
constexpr const int *w = &a;
然后我们有正确的类型,但现在我们有了一个新的错误。 a
不是constexpr
因此它不能在constexpr
初始化中使用,因为它是一个局部变量,并且在运行时只有一个地址。如果我们创建a
static
或全局变量,那么地址将在编译时知道,我们可以在constexpr
中使用它。
答案 1 :(得分:3)
要为变量的某个内存位置指定一个指针,需要使用&
地址运算符:
const int *p = &x;
同样适用于第二个陈述:
*p = &y;
您尝试将变量p
的值设置为而不是指针本身。
尝试:
p = &y;
您不应取消引用以设置指针的位置。星号告诉编译器返回指针指向的值,你不希望这样。
答案 2 :(得分:0)
首先,
const int *p = nullptr;
p
是指向int
指向const
int的指针。这意味着,p
可以指定为指向另一个地址,但是您无法通过解除引用p
来更改p
指向的对象。
int* const p = nullptr;
此处p
是指向const
的{{1}}指针。这意味着您可以通过解除引用int
来更改p
指向的对象,但是您无法更改p
指向的地址。
另一方面,p
表示可以在常量表达式中使用的变量。声明为constexpr
的指针被隐式声明为constexpr
指针。也就是说,
const
与声明相同的一些差异:
constexpr int* p = nullptr;
一个重要的区别是您必须使用静态初始化程序(例如,全局变量的地址)初始化int * const p = nullptr;
指针。
答案 3 :(得分:0)
首先,我担心你会误解这个概念:
int i, j;
const int *ptr = &i;
*ptr = 123; // error
ptr = &j; // ok
使ptr
成为const数据的非常量指针,即您不能通过此指针更改变量i
,但可以更改指针本身。另一方面:
int i, j;
int * const ptr = &i;
*ptr = 123; // ok
ptr = &j; // error
使ptr
为常量指针,因此您可以更改i
的值但不能更改ptr
本身,并且:
int i, j;
const int * const ptr = &i;
*ptr = 123; // error
ptr = &j; // error
使ptr
const指向const数据。
constexr
是完全不同的概念 - 它告诉编译器必须在编译时计算值并保持不变。这就是为什么你不能将局部变量的地址分配给constexpr
指针。