C ++ 11; 非静态数据成员的初始化可以访问其他的数据成员?(C++11; Can non-

2019-06-23 23:41发布

我真的很喜欢在C#属性的想法,作为一个小方项目,我一直在摆弄用C实现它们++的想法。 我就遇到了这个例子https://stackoverflow.com/a/5924594/245869这似乎相当不错,但我忍不住想,lambda表达式和非静态数据成员初始化使得可以使用一些非常漂亮的语法这种想法。 下面是我的实现:

#include <iostream>
#include <functional>

using namespace std;


template< typename T >
class property {

public:
    property(function<const T&(void)> getter, function<void(const T&)> setter)
        : getter_(getter),
          setter_(setter)
    {};

    operator const T&() {
        return getter_();
    };

    property<T>& operator=(const T& value) {
        setter_(value);
    }

private:
    function<const T&(void)> getter_;
    function<void(const T&)> setter_;

};


class Foobar {

public:
    property<int> num {
        [&]() { return num_; },
        [&](const int& value) { num_ = value; }
    };

private:
    int num_;

};


int main() {
    // This version works fine...
    int myNum;
    property<int> num = property<int>(
        [&]() { return myNum; },
        [&](const int& value) { myNum = value; }
    );
    num = 5;

    cout << num << endl;  // Outputs 5
    cout << myNum << endl;  // Outputs 5 again.

    // This is what I would like to see work, if the property
    // member of Foobar would compile...
    // Foobar foo;
    // foo.num = 5;

    // cout << foo.num << endl;

    return 0;
}

我可以使用属性类通常[见在main()的例子],但用的MinGW G ++ 4.7在使用属性作为数据成员并不特别在意我尝试:

\property.cpp: In lambda function:
\property.cpp:40:7: error: invalid use of non-static data member 'Foobar::num_'

因此,似乎我的财产执行的概念作品,但它可能是徒劳的,因为我无法从我的lambda函数访问其他数据成员。 我不知道如何该标准定义了什么我想,我是不是在这里做完全出于运气,还是我只是没有做正确的事情吗?

Answer 1:

您的属性是一个不同的对象(的实例property<int>从含对象(的实例) Foobar )。 因此,它的成员函数获得通过不同的this ,而不是一个你需要访问num_ -所以你不能这样做的。 如果lambda表达式是在的非静态成员函数定义Foobar ,他们会捕获的函数的this参数,并将不得不访问包围对象的成员(明确地,如this->num_ )。 但是lambda表达式在类,其中非静态数据成员实际上并不存在定义。 如果lambda表达式确实有机会获得num_ ,这num_ ,其中实例的Foobar ,本来是什么?

我看到的最简单的解决方案是为属性来存储的指针到封闭的对象。 这样一来,就可以自由地访问其非静态成员。 不足之处是,该声明是稍微复杂一些(你必须做property<int, Foobar> num )和你需要通过将初始化属性this指针。 所以,你将不能够做到这一点的类,它必须是在构造函数中的初始化列表,从而否定C ++ 11的数据成员初始化的优势。

在这一点上, this将是提供给lambda表达式反正捕捉到你的代码实际上最小的变化工作,如果你移动的财产,以Foobar的构造函数(S)的初始化(按价值计算,而不是参考!):

Foobar::Foobar():
    num {
        [this]() { return this->num_; },
        [this](const int& value) { this->num_ = value; }
    }
{
}

有谁知道是否this ,它被传递到任何构造恰好被调用,可在类定义的非静态成员初始化? 我怀疑它是不是,但如果是这样,同样的建设将在类定义内工作。



文章来源: C++11; Can non-static data member initializations access other data members?