【问题标题】:Creating a set of objects [duplicate]创建一组对象[重复]
【发布时间】:2013-12-28 15:26:36
【问题描述】:

我正在尝试创建一组对象。仅仅定义集合是错误的。我现在没有带有 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/stl_function.h:在成员函数'bool std::less<_tp>::operator()(const _Tp&, const _Tp&) 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<_func _return _first>Second>::_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 >' /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 >' t.cpp:35:从这里实例化 第 226 行:错误:'__x

【问题讨论】:

  • 大部分代码是不相关的。问题是Fruit 不满足实例化std::set&lt;Fruit&gt; 的要求。有很多关于这个的问题。
  • 我没有对你投反对票,我认为它在这里也不是很合适,但如果你想避免其他 SO 用户的蔑视,请尝试将你的代码缩小到仍然产生错误的最小部分。在这种情况下,它将是类 Fruit { }; std::set

标签: c++ boost reference


【解决方案1】:

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

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

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

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

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

【讨论】:

  • 我认为 OP 可能需要一个更简单的例子。使 bool operator
  • @PorkyBrain:完成。我喜欢定义一个严格的弱顺序,其中所有对象都是同一个等式类的一部分,尽管...
猜你喜欢
  • 2017-05-07
  • 2022-07-20
  • 2018-07-15
  • 1970-01-01
  • 2021-07-23
  • 1970-01-01
  • 2014-01-30
  • 1970-01-01
  • 2011-10-22
相关资源
最近更新 更多