简体   繁体   English

有没有办法在没有括号的情况下在 C++ 中调用成员的 getter/setter?

[英]Is there a way to call member's getter/setter in C++ without parentheses?

I want to run some GLSL code as a C++ code, by #including it in a C++ application, without modification.我想将一些 GLSL 代码作为C++ 代码运行,方法是#including#including到 C++ 应用程序中,无需修改。 It has no special pragmas and so on, but it has some vector types.它没有特殊的编译指示等,但它有一些向量类型。 For example vec3 and vec4 , that simply means tuple of 3 and 4 floats, respectively, that is contig in memory and convenient for some linear algebra tasks.例如vec3vec4 ,这分别表示 3 个和 4 个浮点数的元组,它们在内存中是重叠的,对于一些线性代数任务很方便。

Pretty everything could be done with operator overloading, except one thing.除了一件事,几乎所有的事情都可以用运算符重载来完成。 Consider that vec4 a has 4 float members: ax , ay , az and aw ;考虑到vec4 a有 4 个浮动成员: axayazaw

In glsl, there is a popular notation a.xyz , that means "take ax,ay,az and construct vec3 from them."在 glsl 中,有一个流行的符号a.xyz ,意思是“获取ax,ay,az并从中构造 vec3”。

Some languages, like Object oriented versions of Pascal(Delphi) has such facility: such members are defined with property keyword in there.一些语言,比如 Pascal(Delphi) 的面向对象版本,有这样的功能:这些成员在那里用property关键字定义。 So when compiler meets it, it calls getter, when it meets assigment - it calls setter, and everything looks like you are reading or writing a regular member variable.所以当编译器遇到它时,它会调用 getter,当它遇到赋值时——它会调用 setter,一切看起来就像你在读或写一个普通的成员变量。

How can we write so in C++?我们如何在 C++ 中这样写?


class vec4 {
public:
    float x,y,z,w;
    property xyz read=get_xyz write=set_xyz; // ??? is there some way?
protected:
    vec3 get_xyz() const { return vec3(x, y, z); }
    void set_xyz(const vec3& v) { x = v.x; y=v.y; z=v.z; }
};

In code then I want to write getter like this:在代码中,我想像这样编写 getter:

vec4 a(1,2,3,4);
auto b = a.xyz; // b = a.get_xyz();

b now is of type vec3 and has x==1 , y==2 , z==3 ; b现在是vec3类型并且有x==1 , y==2 , z==3

And setter like this:像这样的二传手:

vec4 a(1,2,3,4);
a.xyz=vec3(5,6,7); // a.set_xyz(vec3(5,6,7));

a now has x==5 , y==6 , z==7 and w==1 ; a现在有x==5y==6z==7w==1


How could I support such syntax?我怎么能支持这样的语法?

It's a sad fact, that such a mature, powerful and widely-used C++ language has no property support.一个可悲的事实是,如此成熟、强大且广泛使用的 C++ 语言没有property支持。 Even Delphi has.. Luckily, I've managed to solve task (To compile compute glsl shader as C++ without modifying GLSL source).甚至 Delphi 也有......幸运的是,我已经设法解决了任务(将计算 glsl 着色器编译为 C++ 而不修改 GLSL 源代码)。 I think it would not have speed/memory penalty, related to creating proxy objects, and would be easily optimizable by compiler (though this is not needed).我认为它不会有与创建代理对象相关的速度/内存损失,并且可以通过编译器轻松优化(尽管这不是必需的)。

I've found following solution:我找到了以下解决方案:

Try it online! 在线试试吧!

#include <iostream>

#pragma pack(push, 4)
class vec3 {
public:
    float x,y,z;
    vec3() {}
    vec3(float x, float y, float z) :
        x(x), y(y), z(z)
    {}
};

class vec4 {
public:
    union {
        struct {
            float x, y, z, w;
        };
        vec3 xyz;
    };
    vec4() {}
    vec4(float x, float y, float z, float w):
        x(x), y(y), z(z), w(w)
    {}
};

#pragma pack(pop)

int main() {
    {
        vec4 a(1, 2, 3, 4);
        auto b = a.xyz; // b = a.get_xyz();
        std::cout << b.x << b.y << b.z << std::endl;
    }
    {
        vec4 a(1, 2, 3, 4);
        a.xyz = vec3(5, 6, 7); // a.set_xyz(vec3(5,6,7));
        std::cout << a.x << a.y << a.z << a.w << std::endl;
    }
    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM