2013-06-21 10 views
0

获得我无法解决的奇怪错误。我有几个文件,Store.cpp,Store.h(类存储定义在这里),Order.cpp,Order.h(类定义在这里定义)。C++无效的参数,候选人是:“..”来自不同类的Setters

Store.cpp有#include "Order.h"

Order里面我有在公共部分有一些getter和setter方法,其中之一是:

void setStatus(const OrderStatus& orderStatus); 

OrderStatus是一个枚举。

当我试图在Store.cpp与以下行使用它:

(*itr).setStatus(ORDER_DONE); 

我从日食出现此错误:

 
    Invalid arguments ' 
    Candidates are: 
    void setStatus(const enum {order.h:140} &) 
    ' 

而且从GCC这个错误:

 
Store.cpp:250:31: error: no matching function for call to 
âOrder::setStatus(OrderStatus) constâ 
    Store.cpp:250:31: note: candidate is: 
order.h:47:7: note: void Order::setStatus(const OrderStatus&)
order.h:47:7: note: no known conversion for implicit âthisâ parameter from âconst Order*â to âOrder*â

我真的不知道const来自哪里(第250行)。

+0

抱歉,我的意思是你需要一个非const迭代器。 –

+0

这就是即时通讯使用.. \t的(设置:迭代ITR =这个 - > orders.begin(!); \t \t \t ITR =这个 - > orders.end(); ++ ITR) –

+0

@ NadavPeled:设置只允许const访问,否则你可能完全打乱了排序。 – Xeo

回答

3

std::set用于存储不可变的值类型。它们必须是不可变的,因为否则当你改变它们时你可以打破排序约束。

如果要将可变的的值与某个键(由于相同原因而不可变)关联,请改为使用std::map


它的机制是:

std::set<Order>::iterator iter = ...; 
iter->setStatus(ORDER_DONE); 

不起作用,因为*iter产生Order const &和你的方法是不是常量。

我在评论中提到了两种避免此问题的方法,但它们都是通过颠覆const的正确性来实现的,我强烈建议使用而不是使用。但是,对于完整性:

const_cast<Order&>(*iter).setStatus(ORDER_DONE); 

将使编译,因为会改变Order类本身:

class Order { 
    mutable OrderStatus status; 
public: 
    void setStatus(OrderStatus s) const { status = s; } 
}; 

要么这些也可以打破std::set的,如果状态在使用排序不变比较。第一个版本是说“只信任我”并且完全避开const正确性,而第二个版本明确表示状态不是对象状态的“真实”部分,不会用于排序。

说真的,请改用正确的数据结构。

+0

它的作业和设置是我们被要求使用.. 因此,使其工作不可变的唯一方法是从设置中删除元素,编辑它的副本,并插入? –

+1

我怀疑这是唯一的理智方式,是的。如果您正在遍历修改_everything_的集合,则可以将输入集合“转换”为输出集合。 – Useless

2

为了改变set的元素,必须删除元素到本地拷贝,修改它在那里,然后将它装回,

set s为脆弱的,假设的元素不改变它们的顺序而在容器内,这就是为什么访问元素是const