use*_*183 40 c++ operator-overloading language-lawyer
我知道编码风格会很糟糕,但是下面的代码在我的机器上运行得很好.但这种行为是否定义明确?便携式?
int main()
{
int *p = new int[3];
int *q = &p[2];
q[-1] = 41;
std::cout << p[1];
delete[] p;
}
Run Code Online (Sandbox Code Playgroud)
Tar*_*ama 44
这在语法和语义上都有明确的定义.
[expr.sub]/1(N3337):
表达式
E1[E2]
(根据定义)相同*((E1)+(E2))
.
所以你的表达式是一样的*(q-1) = 41;
,语法上也是如此.
[expr.add]/5(N3337)
当向指针添加或从指针中减去具有整数类型的表达式时,结果具有指针操作数的类型.如果指针操作数指向数组对象的元素,并且数组足够大,则结果指向偏离原始元素的元素,使得结果元素和原始数组元素的下标的差异等于整数表达式.
由于q
指向了积分表达式的有效大小的数组对象的元素,因此它在语义上是有效的.
Ben*_*ley 18
是的,它定义明确.内置operator[]
是根据指针算法定义的.这个:
p[N]
Run Code Online (Sandbox Code Playgroud)
where p
是一个指针,N
是一个整数,相当于:
*(p + N)
Run Code Online (Sandbox Code Playgroud)
一个有趣的结果就是:
N[p]
Run Code Online (Sandbox Code Playgroud)
也是等价的,因为加法是可交换的.
根据C++标准(5.2.1订阅)
1后缀表达式后跟方括号中的表达式是后缀表达式.其中一个表达式应具有"T的数组"类型或"指向T的指针",另一个表达式应具有未映射的枚举或整数类型.结果是类型"T".类型"T"应该是完全定义的对象类型.65表达式E1 [E2]与*((E1)+(E2))相同(...(E1)+(E2))...
所以你可以使用任何整数类型,包括类型int
和相应的负值,只要表达的结果*((E1)+(E2))
是良好的形式.
考虑到对于用户定义的类型,您可以使用brace-init-list作为索引.例如
#include <iostream>
class Point
{
public:
Point( int x, int y ) : x( x ), y( y ) {}
int x, y;
};
class Circle
{
public:
Circle( unsigned int r ) : r( r ) {}
Circle & operator []( Point p )
{
std::cout << "Drawing a circle at ( " << p.x << ", " << p.y << " )\n";
return *this;
}
unsigned int r;
};
int main()
{
Circle circle( 10 );
circle[ { 0, 0 } ];
}
Run Code Online (Sandbox Code Playgroud)
程序输出是
Drawing a circle at ( 0, 0 )
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
2480 次 |
最近记录: |