基于C++模板指针到成员的属性实现的一些麻烦

Zer*_*can 4 c++ templates properties

我的目标是在C++中创建属性,就像在C#中一样 - 具有非平凡的set/get行为.这里,Property的对象持有refs来掌握prop及其set/get方法.

Property.h的实现,内容:

#include <iostream>

using namespace std;

namespace First {

    template <class Master, class Type>
    struct Property
    {
        Master &master;

        const Type (Master::*&get) () const;
        Type (Master::*&set)(Type value);

        Property
        (
            Master &master, 
            const Type (Master::*get) () const, 
            Type (Master::*set)(Type value)
        ): 
            get(get), 
            set(set), 
            master(master) 
        { }

        operator const Type() const { cout << "inside" << endl; return (master.*get)(); }

        Type operator = (Type value)
        {
            return (master.*set)(value);
        }
    };

    // Test chamber.
    class R
    {
        float x;
        const float getx() const { cout << "returning " << 0 << endl; return 0; }
        float setx(float value) { cout << "setting " << value << " in place of " << x << endl; return x = value; }
    public:
        Property<R, float> X;

        R(): X(*this, &R::getx, &R::setx) { }
    };

}
Run Code Online (Sandbox Code Playgroud)

我还创建了.cpp文件:

#include "Property.h"

using namespace First;

int main()
{
    R r;

    r.X = 10;

    float y = r.X;

}
Run Code Online (Sandbox Code Playgroud)

该程序进行"分配"步骤,打印'设置0到10',但是在调用"检索"步骤时段错误,在'R :: getx()'内没有区别什么代码(或根本没有).

~/Sources$ ./a.out          

setting 10 in place of 0
inside
zsh: segmentation fault  ./a.out
Run Code Online (Sandbox Code Playgroud)

似乎调用(master.*get())本身会导致失败.这段代码有什么问题?

UPD:测试了对master函数的任何其他调用导致段错误,只有一次调用(master.*set)成功.似乎此调用使对象状态,成员到ptr,属性本身或月相无效.

Naw*_*waz 6

const Type (Master::*&get) () const;
Type (Master::*&set)(Type value);
Run Code Online (Sandbox Code Playgroud)

&从以上定义中删除.因为&,每个都绑定到构造函数返回后不存在的构造函数参数.

还要注意它似乎(master.*set)(value)有效,因为你不走运.它实际上调用了未定义的行为.但是你很幸运,很快你就会在(master.*get)()失败时知道问题,给出段错误.

使用:

const Type (Master::*get) () const;
Type (Master::*set)(Type value);
Run Code Online (Sandbox Code Playgroud)

它应该现在可以正常工作,没有任何问题,因为它会导致初始化列表中的地址副本,而不是引用参数!