用C ++方式别名化struct和array [英] Aliasing struct and array the C++ way

查看:122
本文介绍了用C ++方式别名化struct和array的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的另一个问题的C ++跟踪

This is a C++ followup for another question of mine

在ISO C之前的年代,以下代码不会让任何人感到惊讶:

In the old days of pre-ISO C, the following code would have surprised nobody:

struct Point {
    double x;
    double y;
    double z;
};
double dist(struct Point *p1, struct Point *p2) {
    double d2 = 0;
    double *coord1 = &p1->x;
    double *coord2 = &p2->x;
    int i;
    for (i=0; i<3; i++) {
        double d = coord2[i]  - coord1[i];    // THE problem
        d2 += d * d;
    }
    return sqrt(d2);
}

不幸的是,这条有问题的行使用了指针算术(p[i]根据定义是 *(p + i))在标准明确不允许的任何数组之外.C++ 17的草案4659中指出8.7 [expr.add]:

Unfortunately, this problematic line uses pointer arithmetic (p[i] being by definition *(p + i)) outside of any array which is explicitely not allowed by the standard. Draft 4659 for C++17 says in 8.7 [expr.add]:

如果表达式P指向具有n个元素的数组对象x的元素x [i], 表达式P + J和J + P(其中J的值为j)指向(可能是假设的)元素 如果0≤i + j≤n,则x [i + j];否则,行为是不确定的.

If the expression P points to element x[i] of an array object x with n elements, the expressions P + J and J + P (where J has the value j) point to the (possibly-hypothetical) element x[i + j] if 0 <= i + j <= n; otherwise, the behavior is undefined.

(非规范性的)注释86使其更加明确:

And the (non-normative) note 86 makes it even more explicit:

为此,非数组元素的对象被视为属于单元素数组.一种 经过n个元素中的x个元素的数组的最后一个元素的指针被认为等效于指向假设元素的指针 x [n]为此.

An object that is not an array element is considered to belong to a single-element array for this purpose. A pointer past the last element of an array x of n elements is considered to be equivalent to a pointer to a hypothetical element x[n] for this purpose.

所引用问题的可接受答案使用了以下事实:C语言通过联合接受 type punning ,但我再也找不到C ++标准中的等效语言了.因此,我假设包含匿名结构成员和数组的联合将导致C ++中的Undefined Behaviour -它们不同的语言...

The accepted answer of the referenced question uses the fact that the C language accepts type punning through unions, but I could never find the equivalent in the C++ standard. So I assume that a union containing an anonymous struct member and an array would lead to Undefined Behaviour in C++ — they are different languages...

什么样的一致性方法可以遍历结构的成员,就好像它们是C ++中数组的成员一样?我正在寻找当前(C ++ 17)版本的方法,但是也欢迎使用旧版本的解决方案.

What could be a conformant way to iterate through members of a struct as if they were members of an array in C++? I am searching for a way in current (C++17) versions, but solutions for older versions are also welcome.

它显然仅适用于相同类型的元素,并且可以通过简单的assert检测填充,如其他问题所示,因此填充,对齐和混合类型不是我的问题.

It obviously only applies to elements of same type, and padding can be detected with a simple assert as shown in that other question, so padding, alignment, and mixed types are not my problem here.

推荐答案

使用指向成员的constexpr数组:

Use an constexpr array of pointer-to-member:

#include <math.h>

struct Point {
    double x;
    double y;
    double z;
};

double dist(struct Point *p1, struct Point *p2) {
    constexpr double Point::* coords[3] = {&Point::x, &Point::y, &Point::z};

    double d2 = 0;
    for (int i=0; i<3; i++) {
        double d = p1->*coords[i] - p2->*coords[i];
        d2 += d * d;
    }
    return sqrt(d2);
}

这篇关于用C ++方式别名化struct和array的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆