【问题标题】:How exactly does constexpr double Point::* coords[3] work? [duplicate]constexpr double Point::* coords[3] 究竟是如何工作的? [复制]
【发布时间】:2020-11-26 18:54:33
【问题描述】:

所以我一直在看一些东西,发现这个帖子Aliasing struct and array the C++ way

,这是问题的答案

#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);
}

现在我的问题是我不知道是什么

constexpr double Point::* coords[3] = {&Point::x, &Point::y, &Point::z};

应该这样做...

我知道constexpr 使它成为在编译时定义的常量,并且显然使用了double,因为该结构包含双精度,但Point::*{&amp;Point::x, &amp;Point::y, &amp;Point::z}; 让我感到困惑。首先是什么是Point::*?我猜 * 表示它是某种指针,但指向什么?以及这些地址{&amp;Point::x, &amp;Point::y, &amp;Point::z}

此整个表达式究竟是什么定义?

【问题讨论】:

    标签: c++ pointers struct


    【解决方案1】:

    此语法是pointer to member,本质上是一种将成员存储到变量并检索它的方法。当您想要循环访问成员列表时,这对于这种情况很有用。

    【讨论】:

    • 您说“对这种情况有用”,但我发现这种特定用法非常可疑。它比“手动”代码更长,使用更多的间接层,可读性更差,甚至效率不高(不测试它我相信编译器将能够展开循环并内联变量访问,但通过这样做所以即使使用手动版本,它所做的只是绘制)。
    • 首先,使用范围 for 循环,代码看起来会好很多。其次,因为数组是 constexpr,所以您可以通过模板参数提供任何数组。这意味着为 vec2、vec3 和 vec4 提供一个函数,同时将函数作为一个整体设置为 constexpr,这肯定会有所帮助。但这永远不会在向量数学库中使用,因为它可能在 SSE 优化方面存在问题。
    猜你喜欢
    • 2012-01-26
    • 2019-10-12
    • 1970-01-01
    • 2023-03-16
    • 2012-10-07
    • 2020-10-17
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    相关资源
    最近更新 更多