草庐IT

c++ - 具有 const 成员的对象的优先级队列比较器

coder 2024-02-17 原文

我正在尝试实现一个优先级队列,它使用一个对象,该对象具有一个常量成员,用于定义队列中对象的优先级。以下是我正在使用的精简版

#include <vector>
#include <queue>

class Event {
public:
    Event(float _time) : time(_time) {};
    const float time;
};

struct EventComp {
public:
    bool operator()(const Event& a, const Event& b) const {
      return a.time < b.time;
    }
};

class EventQueue {
private:
    std::priority_queue<Event, std::vector<Event>, EventComp> events;
};


int main(int argc, char *argv[])
{
    EventQueue q;
}

当我尝试编译(使用 g++ -std=c++11)时,我收到以下错误消息,我不太明白。

g++ -std=c++11 events.cpp -o events
In file included from /usr/include/c++/4.8/queue:62:0,
                 from events.cpp:2:
/usr/include/c++/4.8/bits/stl_heap.h: In instantiation of ‘void std::__adjust_heap(_RandomAccessIterator, _Distance, _Distance, _Tp, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Event*, std::vector<Event> >; _Distance = long int; _Tp = Event; _Compare = EventComp]’:
/usr/include/c++/4.8/bits/stl_heap.h:448:15:   required from ‘void std::make_heap(_RandomAccessIterator, _RandomAccessIterator, _Compare) [with _RandomAccessIterator = __gnu_cxx::__normal_iterator<Event*, std::vector<Event> >; _Compare = EventComp]’
/usr/include/c++/4.8/bits/stl_queue.h:411:48:   required from ‘std::priority_queue<_Tp, _Sequence, _Compare>::priority_queue(const _Compare&, _Sequence&&) [with _Tp = Event; _Sequence = std::vector<Event>; _Compare = EventComp]’
events.cpp:15:7:   required from here
/usr/include/c++/4.8/bits/stl_heap.h:315:29: error: use of deleted function ‘Event& Event::operator=(Event&&)’
    *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first + __secondChild));
                             ^
events.cpp:4:7: note: ‘Event& Event::operator=(Event&&)’ is implicitly deleted because the default definition would be ill-formed:
 class Event {
       ^
events.cpp:4:7: error: non-static const member ‘const float Event::time’, can’t use default assignment operator
In file included from /usr/include/c++/4.8/queue:62:0,
                 from events.cpp:2:
/usr/include/c++/4.8/bits/stl_heap.h:321:29: error: use of deleted function ‘Event& Event::operator=(Event&&)’
    *(__first + __holeIndex) = _GLIBCXX_MOVE(*(__first
                             ^

我假设 priority_queue 内部结构的某些部分需要移动赋值运算符来插入元素,但是 const 成员似乎阻止了该运算符的定义.我尝试使用五的规则,但似乎没有成功。我需要在类定义中添加什么才能使其正常工作?

编辑:我知道我可以从成员变量中删除 const 限定符,使其成为 private,并添加一个访问成员函数来获取变量,但我宁愿拥有它 publicconst,所以我对保持示例中的成员变量的解决方案感兴趣(如果它是偶数可能)。

最佳答案

std::priority_queue<Event, ...> 的默认构造函数需要 Event成为MoveAssignable因为它调用 std::make_heap (有这个要求)。 Event不是 MoveAssignable因为 const float time数据成员。如果删除 const来自该数据成员的限定符,您的代码应该可以编译。

I'm aware that I can remove the const qualifier from the member variable, make it private, and add an accessor member function to get the value of the variable, but I would rather have it public and const, so I'm interested in solutions which keep the member variable as it is in the example (if that is even possible).

最终,要使用这个 std::lib 工具,EventMoveAssignable .此要求可以通过移动赋值运算符或复制赋值运算符来满足。您或编译器可以提供其中一个或两个。但是当你有一个 const数据成员,编译器提供的特殊成员将被隐式删除。

如果需要,请继续提供您自己的复制和/或移动赋值运算符:

class Event {
public:
    Event(float _time) : time(_time) {};
    const float time;

    Event(Event&&) = default;
    Event& operator=(Event&&);  // Supply this
};

对于您可能希望移动(或复制)赋值运算符做什么,我没有很好的猜测,因为您已经声明一旦构建,您就不需要 time永远改变。这是您必须制定的设计决策(与一般的软件设计有关,而不是 C++ 语法)。


<aside>

在问题的评论中POW请注意,问题中的代码使用 clang 编译(更准确地说,使用 libc++ )。这样做的原因是 libc++ 中的一个几乎符合标准的扩展:

标准规定了这个priority_queue构造函数:

explicit priority_queue(const Compare& x = Compare(),
                        Container&& c = Container());

调用std::make_heap与容器 c .但该标准还为实现者提供了余地,可以使用默认值和等效重载替换成员函数签名。 libc++ 将此单一签名替换为以下三个:

priority_queue();
explicit priority_queue(const Compare& x);
explicit priority_queue(const Compare& x, Container&& c);

只有第 3 个需要调用 std::make_heap .因此,libc++ 中的默认构造函数对 value_type 的要求较少。 .

我说几乎符合要求。不完全符合的部分是未声明默认构造函数explicit .这是实现者有意做出的设计决定 priority_queue更易于使用。

</aside>

关于c++ - 具有 const 成员的对象的优先级队列比较器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27670205/

有关c++ - 具有 const 成员的对象的优先级队列比较器的更多相关文章

  1. ruby - 如何从 ruby​​ 中的字符串运行任意对象方法? - 2

    总的来说,我对ruby​​还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用

  2. ruby-on-rails - 按天对 Mongoid 对象进行分组 - 2

    在控制台中反复尝试之后,我想到了这种方法,可以按发生日期对类似activerecord的(Mongoid)对象进行分组。我不确定这是完成此任务的最佳方法,但它确实有效。有没有人有更好的建议,或者这是一个很好的方法?#eventsisanarrayofactiverecord-likeobjectsthatincludeatimeattributeevents.map{|event|#converteventsarrayintoanarrayofhasheswiththedayofthemonthandtheevent{:number=>event.time.day,:event=>ev

  3. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

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

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

  5. ruby-on-rails - 如何验证非模型(甚至非对象)字段 - 2

    我有一个表单,其中有很多字段取自数组(而不是模型或对象)。我如何验证这些字段的存在?solve_problem_pathdo|f|%>... 最佳答案 创建一个简单的类来包装请求参数并使用ActiveModel::Validations。#definedsomewhere,atthesimplest:require'ostruct'classSolvetrue#youcouldevencheckthesolutionwithavalidatorvalidatedoerrors.add(:base,"WRONG!!!")unlesss

  6. Ruby 写入和读取对象到文件 - 2

    好的,所以我的目标是轻松地将一些数据保存到磁盘以备后用。您如何简单地写入然后读取一个对象?所以如果我有一个简单的类classCattr_accessor:a,:bdefinitialize(a,b)@a,@b=a,bendend所以如果我从中非常快地制作一个objobj=C.new("foo","bar")#justgaveitsomerandomvalues然后我可以把它变成一个kindaidstring=obj.to_s#whichreturns""我终于可以将此字符串打印到文件或其他内容中。我的问题是,我该如何再次将这个id变回一个对象?我知道我可以自己挑选信息并制作一个接受该信

  7. ruby-on-rails - 如果 Object::try 被发送到一个 nil 对象,为什么它会起作用? - 2

    如果您尝试在Ruby中的nil对象上调用方法,则会出现NoMethodError异常并显示消息:"undefinedmethod‘...’fornil:NilClass"然而,有一个tryRails中的方法,如果它被发送到一个nil对象,它只返回nil:require'rubygems'require'active_support/all'nil.try(:nonexisting_method)#noNoMethodErrorexceptionanymore那么try如何在内部工作以防止该异常? 最佳答案 像Ruby中的所有其他对象

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

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

  9. ruby - 如何在 Rails 4 中使用表单对象之前的验证回调? - 2

    我有一个服务模型/表及其注册表。在表单中,我几乎拥有服务的所有字段,但我想在验证服务对象之前自动设置其中一些值。示例:--服务Controller#创建Action:defcreate@service=Service.new@service_form=ServiceFormObject.new(@service)@service_form.validate(params[:service_form_object])and@service_form.saverespond_with(@service_form,location:admin_services_path)end在验证@ser

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

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

随机推荐