创建一组对象

Creating a set of objects

本文关键字:一组 对象 创建      更新时间:2023-10-16

我正在尝试创建一组对象。仅仅定义集合就会产生错误。我现在没有带boost的编译器。所以我使用了一个在线IDE。这是代码的链接http://codepad.org/UsBAMmuh.不知怎么的,它似乎不起作用。最后,我想在另一个类的构造函数中传递对该集合的引用。

#include <iostream>
#include <boost/optional.hpp>
#include <boost/ref.hpp>
#include <boost/serialization/vector.hpp> 
using namespace std;
class Fruit {
};
class Env
{
    public:
    Env(std::set<Fruit>& apples);
    std::set<Fruit>& GetApples() const;
    void AddApple(Fruit const& fruit);
    private:
    std::set<Fruit>& _apples;
};
Env::Env(std::set<Fruit>& apples):
_apples(apples)
{
}
std::set<Fruit>& Env::GetApples() const
{
return _apples;
}
void Env::AddApple(Fruit const& fruit)
{
this->_apples.insert(fruit);
}
class EnvHolder{
public:
void SetEnv (Env const& env);
Env& GetEnv()const;
private:
boost::scoped_ptr<Env> _env;
};
void EnvHolder::SetEnv(Env const& env)
{
this->_env.reset(new Env(env));
}
Env& EnvHolder::GetEnv() const
{
return *this->_env;
}
int main() {
std::set<Fruit> fruits;
//Fruit *fr = new Fruit();
//fruits.insert(*fr);
//Env env(fruits);
cout << "Hello" << endl;
return 0;
}

我得到以下错误:

/usr/local/lib/gcc/i686-pc-linux gnu/4.1.2/../../../include/c++/4.1.2/bits/sstl_function.h:在成员函数'bool std::less&lt_Tp>::运算符()(const_Tp&,const_Tp&amp;)const[with_Tp=Fruit]':/usr/local/lib/gcc/i686-pc-linux gnu/4.1.2/../../../include/c++/4.1.2/bits/boost_concept_check.h:358:从'void __gnu_cxx::_BinaryFunctionConcept&lt_Func,_Return,_First,Second>::_contraints()[其中_Func=std::less,_Return=bool,_First=Fruit,_Second=Fruit]'/usr/local/lib/gcc/i686-pc-linux gnu/4.1.2/../../../include/c++/4.1.2/bits/sstl_set.h:112:从'__gnu_norm::set,std::allocater>'实例化/usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../include/c++/4.1.2/debug/set.h:45:从'__gno_debug_def::set,std::allocater>'实例化t.cpp:35:从这里实例化第226行:错误:"operator<"不匹配在'__x&lt__y由于-W致命错误,编译终止。

当您想将类的对象放入关联容器(例如std::set<T>)中时,您需要提供一些方法来识别该容器中的对象。有序关联容器(std::map<K, V>std::set<T>及其"多"版本)使用严格的弱排序来识别对象。这意味着您可以定义一个合适的小于运算符,也可以在定义std::set<T>时提供一个比较类型。对于初学者来说,定义小于运算符可能是最简单的,例如:

class Fruit {
    std::string name_;
public:
    Fruit(std::string const& name): name_(name) {}
    std::string name() const { return this->name_; }
};
bool operator<  (Fruit const& f0, Fruit const& f1) {
    return f0.name() < f1.name();
}
bool operator>  (Fruit const& f0, Fruit const& f1) { return (f1 < f0); }
bool operator<= (Fruit const& f0, Fruit const& f1) { return !(f1 < f0); }
bool operator>= (Fruit const& f0, Fruit const& f1) { return !(f0 < f1); }

虽然添加这些运算符会使代码编译,但可能不会使其工作得太好:由于Fruit类没有成员,因此无法区分它们。因此,所有Fruit对象都被认为是同一等价类中的。对于一个实际的Fruit类,您将有一些成员,并根据它们对对象进行排序。

虽然严格来说只需要operator<(),但提供其他关系运算符也是合理的。不过,它们看起来总是一样的,即它们只是委托给operator<()。除了选择实现全套关系运算符外,代码还选择将比较运算符实现为非成员函数:运算符也可以实现为成员函数。但是,如果涉及隐式转换,则成员运算符的行为是不对称的:允许在右侧操作数上进行转换,但不允许在左侧操作数上执行转换。非成员实现使转换行为对称。

使用比较类型看起来像这样:

struct FruitCmp {
    bool operator()(Fruit const& f0, Fruit const& f1) const {
        return f0.name() < f1.name();
    }
};
std::set<Fruit, FruitCmp> setOfFruit;

当然,在false返回的所有这些情况下,需要执行实现严格弱排序的适当逻辑。通常,最简单的方法是根据关键成员的字典比较来定义比较。