创建一组对象

时间:2013-12-10 21:42:29

标签: c++ boost reference

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

#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 /../../../../包括/ C ++ / 4.1.2 /比特/ stl_function.h:在成员函数'bool std :: less&lt; _Tp&gt; :: operator()(const _Tp&amp;,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&gt; :: _constraints()[with _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/stl_set.h:112:实例化来自'__gnu_norm :: set,std :: allocator&gt;' /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../include/c++/4.1.2/debug/set.h:45:实例化来自'__gnu_debug_def :: set,std :: allocator&gt;' t.cpp:35:从这里实例化 第226行:错误:'operator&lt;'不匹配在'__x&lt; __y” 由于-Wfatal-errors而导致编译终止。

1 个答案:

答案 0 :(得分:2)

如果要将类的对象放入关联容器(例如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返回的所有这些情况下,需要执行实现严格弱顺序的正确逻辑。通常,最简单的方法是根据关键成员的词典比较来定义比较。