目前的标准草案(可能是C++ 17)在[basic.compound/4]中说:
[注意:数组对象及其第一个元素不是指针可互换的,即使它们具有相同的地址. - 结束说明]
因此,指向对象的指针不能reinterpret_cast获得其封闭的数组指针.
现在,有std::launder,[ptr.launder/1]:
template<class T> [[nodiscard]] constexpr T* launder(T* p) noexcept;要求:
p表示内存中字节的地址A. 在其生命周期内且其类型类似于T的对象X位于地址A处.可通过结果到达的所有存储字节都可通过p(见下文)到达.
和的definion 可达是在[ptr.launder/3] :
备注:只要可以在核心常量表达式中使用其参数的值,就可以在核心常量表达式中使用此函数的调用.如果对象Y位于Y所占用的存储区内,则指向存储的字节可以到达,如果Y是指针可互换的对象,则指向对象Y,或者如果Y是数组元素,则指向立即封闭的数组对象.如果T是函数类型或cv void,则程序格式错误.
现在,乍一看,似乎std::launder可以用来做上述转换,因为我强调的部分.
但.如果p指向数组的对象,则根据此定义可以访问数组的字节(即使p不是指针可互换为数组指针),就像清洗的结果一样.因此,该定义似乎没有说明这个问题.
那么,可以std::launder用来将对象指针转换为其封闭的数组指针吗?
int (*arr)[5]means arr是一个包含5个整数的指针数组.现在究竟是什么指针?
如果我声明指向第一个元素的指针int arr[5]在哪里,它是否相同arr?
是arr从两个例子是一样的吗?如果没有,那么究竟什么是指向数组?
在 C++ 中,不带括号的数组名称是指向数组第一个元素的指针。但是,我无法意识到以下代码是如何工作的
int main()
{
int x[] = {1, 2, 3, 4};
cout << "x = " << x << endl;
cout << "&x = " << &x << endl;
cout << "*(&x) = " << *(&x) << endl;
cout << "*x = " << *x << endl;
cout << "**(&x) = " << **(&x) << endl;
}
Run Code Online (Sandbox Code Playgroud)
这是输出
x = 0x7ffd179e9060
&x = 0x7ffd179e9060
*(&x) = 0x7ffd179e9060
*x = 1
**(&x) = 1
Run Code Online (Sandbox Code Playgroud)
我不明白的是
x = &x …