草庐IT

C++11;非静态数据成员初始化可以访问其他数据成员吗?

coder 2024-02-05 原文

我真的很喜欢 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()] 中的示例],但是带有 g++4.7 的 MinGW 并不特别关心我尝试将该属性用作数据成员:

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

所以我的属性实现的概念似乎有效,但它可能是徒劳的,因为我无法从我的 lambda 函数访问其他数据成员。我不确定标准如何定义我在这里尝试做的事情,我是完全不走运,还是我只是没有在这里做某事?

最佳答案

您的属性是与包含对象(property<int> 的实例)不同的对象(Foobar 的实例)。因此,它的成员函数被传递给一个不同的 this。 ,而不是您需要访问的 num_ ——所以你不能那样做。如果 lambda 是在 Foobar 的非静态成员函数中定义的, 他们会捕获该函数的 this参数并且可以访问封闭对象的成员(明确地,作为 this->num_ )。但是 lambda 是在类中定义的,其中非静态数据成员实际上并不存在。如果 lambda 确实可以访问 num_ ,这num_ ,其中 Foobar 的实例, 会是这样吗?

我看到的最简单的解决方案是让属性存储指向封闭对象的指针。这样,它就可以自由访问其非静态成员。缺点是声明稍微复杂一些(您必须执行 property<int, Foobar> num )并且您需要通过传递 this 来初始化属性指针。所以你不能在类中这样做,它必须在构造函数的初始化列表中,因此否定了 C++11 的数据成员初始化的优势。

那时,this lambdas 无论如何都可以捕获(按值,而不是按引用!)所以如果您将属性的初始化移动到 Foobar 的构造函数,您的代码实际上可以进行最小的更改:

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

有谁知道this ,传递给恰好被调用的任何构造函数,是否可用于类定义中的非静态成员初始化?我怀疑不是,但如果是的话,相同的构造将在类定义中起作用。

关于C++11;非静态数据成员初始化可以访问其他数据成员吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10333736/

有关C++11;非静态数据成员初始化可以访问其他数据成员吗?的更多相关文章

  1. ruby - 其他文件中的 Rake 任务 - 2

    我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时

  2. ruby - 如何将脚本文件的末尾读取为数据文件(Perl 或任何其他语言) - 2

    我正在寻找执行以下操作的正确语法(在Perl、Shell或Ruby中):#variabletoaccessthedatalinesappendedasafileEND_OF_SCRIPT_MARKERrawdatastartshereanditcontinues. 最佳答案 Perl用__DATA__做这个:#!/usr/bin/perlusestrict;usewarnings;while(){print;}__DATA__Texttoprintgoeshere 关于ruby-如何将脚

  3. ruby-on-rails - 未初始化的常量 Psych::Syck (NameError) - 2

    在我的gem中,我需要yaml并且在我的本地计算机上运行良好。但是在将我的gem推送到ruby​​gems.org之后,当我尝试使用我的gem时,我收到一条错误消息=>"uninitializedconstantPsych::Syck(NameError)"谁能帮我解决这个问题?附言RubyVersion=>ruby1.9.2,GemVersion=>1.6.2,Bundlerversion=>1.0.15 最佳答案 经过几个小时的研究,我发现=>“YAML使用未维护的Syck库,而Psych使用现代的LibYAML”因此,为了解决

  4. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  5. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

    我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

  6. ruby-on-rails - 未在 Ruby 中初始化的对象 - 2

    我在Rails工作并有以下类(class):classPlayer当我运行时bundleexecrailsconsole然后尝试:a=Player.new("me",5.0,"UCLA")我回来了:=>#我不知道为什么Player对象不会在这里初始化。关于可能导致此问题的操作/解释的任何建议?谢谢,马里奥格 最佳答案 havenoideawhythePlayerobjectwouldn'tbeinitializedhere它没有初始化很简单,因为你还没有初始化它!您已经覆盖了ActiveRecord::Base初始化方法,但您没有调

  7. ruby-on-rails - Rails 模型——非持久类成员或属性? - 2

    对于Rails模型,是否可以/建议让一个类的成员不持久保存到数据库中?我想将用户最后选择的类型存储在session变量中。由于我无法从我的模型中设置session变量,我想将值存储在一个“虚拟”类成员中,该成员只是将值传递回Controller。你能有这样的类(class)成员吗? 最佳答案 将非持久属性添加到Rails模型就像任何其他Ruby类一样:classUser扩展解释:在Ruby中,所有实例变量都是私有(private)的,不需要在赋值前定义。attr_accessor创建一个setter和getter方法:classUs

  8. ruby-on-rails - ActionController::RoutingError: 未初始化常量 Api::V1::ApiController - 2

    我有用于控制用户任务的Rails5API项目,我有以下错误,但并非总是针对相同的Controller和路由。ActionController::RoutingError:uninitializedconstantApi::V1::ApiController我向您描述了一些我的项目,以更详细地解释错误。应用结构路线scopemodule:'api'donamespace:v1do#=>Loginroutesscopemodule:'login'domatch'login',to:'sessions#login',as:'login',via::postend#=>Teamroutessc

  9. ruby - Ruby 有 `Pair` 数据类型吗? - 2

    有时我需要处理键/值数据。我不喜欢使用数组,因为它们在大小上没有限制(很容易不小心添加超过2个项目,而且您最终需要稍后验证大小)。此外,0和1的索引变成了魔数(MagicNumber),并且在传达含义方面做得很差(“当我说0时,我的意思是head...”)。散列也不合适,因为可能会不小心添加额外的条目。我写了下面的类来解决这个问题:classPairattr_accessor:head,:taildefinitialize(h,t)@head,@tail=h,tendend它工作得很好并且解决了问题,但我很想知道:Ruby标准库是否已经带有这样一个类? 最佳

  10. ruby - 这两个 Ruby 类初始化定义有什么区别? - 2

    我正在阅读一本关于Ruby的书,作者在编写类初始化定义时使用的形式与他在本书前几节中使用的形式略有不同。它看起来像这样:classTicketattr_accessor:venue,:datedefinitialize(venue,date)self.venue=venueself.date=dateendend在本书的前几节中,它的定义如下:classTicketattr_accessor:venue,:datedefinitialize(venue,date)@venue=venue@date=dateendend在第一个示例中使用setter方法与在第二个示例中使用实例变量之间是

随机推荐