2013-12-10 138 views
-3

我想創建一組對象。僅僅定義這個集合會給出錯誤。我現在沒有一個編譯器可以提升。所以我使用了一個在線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:實例化from'void __gnu_cxx :: _ BinaryFunctionConcept < _Func,_Return,_First,Second> :: _constraints()[with _Func = std :: le ss,_Return = bool,_First =水果,_Second =水果]' /usr/local/lib/gcc/i686-pc-linux-gnu/4.1.2/../../../../..lude /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 < __y'中的'運營商<'不匹配 編譯因 - 重大錯誤而終止。

+1

大部分代碼都是不相關的。問題是'Fruit'不滿足實例化'std :: set '的要求。這裏有很多SO問題。 – juanchopanza

+1

我並沒有降低你的評價,也沒有認爲它在這裏非常合適,但如果你想避免其他SO用戶的嘲諷,試着將代碼縮小到仍然產生錯誤的最小片段。在這種情況下,它將是水果類{ }; std :: set odinthenerd

回答

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是恢復實施嚴格的弱序需要去正確的邏輯。通常,最簡單的方法是根據關鍵成員的字典對比來定義比較。

+0

我認爲OP可能需要一個更簡單的例子。使bool運算符<(果實const&f0,果實const&f1){返回false; }實際上比較水果中的某些東西(因此他可以將其中一個以上的東西放入他的集合中),我會刪除我的答案,因爲您的答案會更好。 – odinthenerd

+0

@PorkyBrain:完成。我喜歡定義一個嚴格的弱順序,其中所有的對象都是同一個相等類的一部分,儘管... –