2011-05-18 87 views
0

在我的程序中,我得到一個字符串,它由屬性名和屬性值組成。例如:string X 2。我的問題是,我有很多屬性,他們有不同的類型。它可以是int,boolean或枚舉。例如,X 2應該是int x = 2;STATUS 0應該是bool status = false等等。在C++中的強制屬性

所以我需要讀取字符串,並創建具有值取決於字符串的屬性。我想到了hash_map,但也許你有另一個想法?

我也不知道我怎麼能把類型的屬性放在hash_map中。 事情是這樣的:

typedef unordered_map<string, type> MapType; 

我知道的hash_map如何與函數指針;也許有類型的東西。這可以給我一個參考,例如,int,布爾,並且我可以搜索地圖並從我的字符串中轉換值。

+0

新句子以大寫字母開頭。 – 2011-05-18 18:59:01

+1

它不是很容易回答,因爲它涉及語義:「狀態0」爲什麼布爾狀態= false而不是整數int狀態= 0? – ascanio 2011-05-18 18:59:40

+0

@Kiril Kirov如果它困擾你很多,編輯按鈕就在那裏。 – tenpn 2011-05-18 19:00:58

回答

0

充分利用配置文件或東西不同類型(布爾,整數,字符串...)的值是這已經解決了問題解決了多少次......也許太多次了:)

看一看它是如何在Boost.Program_optionscfgparserIniReader完成,...

+0

是的,但它不能解決我的問題。這不是我想要的。 :-) 之前我打電話一些功能 例如 ReadFloat(http://www.codeproject.com/KB/cpp/IniReader.aspx)。我需要知道我在STRING中擁有Float值。這是我的問題。 – cheloveg 2011-05-18 19:08:39

+0

並且boost會使用utree或Property Tree再次解決下一個版本 – sehe 2011-05-18 19:15:11

1

你可以使用一個map<string, string>類型存儲的屬性你加載/從字符串如「X 2」或「STATUS 0」閱讀。接下來,編寫一門課,例如AttributesContainer充當地圖的包裝,以作爲方法getString(string key)getInt(string key)getBoolean(string key)

因此,根據主叫方和被叫get方法,您可以從地圖上取決於你的首選解釋值邏輯。如果調用getBoolean,則可以將0/1解釋爲布爾值,但如果調用getInt,則返回int 0或1。

+0

我認爲這是迄今爲止OP最常見的答案。 – Nim 2011-05-18 22:45:37

0

這可以用工廠模式完成,但您需要有一個根類派生自。例如,工廠如何返回指向string的指針或指向bool的指針?

這些對象是如何使用的?

另一個建議是對每種類型的對象都有一個vector,並且有兩個容器,一個用於創建對象的函數,另一個用於創建函數的函數指針。 使用其中一個地圖來獲取創建項目的功能。 使用其他地圖獲取該物品的矢量。 通過傳遞正確的矢量執行該功能。

否則,它指向void

0

我不能相信我將要提出這一點,但在這裏不用...

定義一個簡單的attribute類,這是圍繞std::string的包裝 - 這是你的價值。這個類應該提供轉換操作符(儘管我不喜歡它們,在這種情況下,它們可以使生活變得更容易)。

#include <iostream> 
#include <boost/lexical_cast.hpp> 

struct attribute 
{ 
    std::string value; 

    operator bool() const { return boost::lexical_cast<bool>(value); } 
    operator int() const { return boost::lexical_cast<int>(value); } 
    operator unsigned int() const { return boost::lexical_cast<unsigned int>(value); } 
    operator double() const { return boost::lexical_cast<double>(value); } 
    operator std::string() const { return value; } 
}; 

int main(void) 
{ 
    attribute a = { "foo" }; 
    attribute b = { "10" }; 

    std::string sa = a; 
    int sb = b; 
    unsigned int su = b; 

    std::cout << sa << std::endl; 
    std::cout << sb << std::endl; 
    std::cout << su << std::endl; 
} 

所以在這裏,您分配的變量的類型決定了應用的轉換。現在使用這種方法的主要問題是,如果沒有直接轉換運算符,編譯器將選擇最佳匹配 - 這可能並不總是您想要的。所以爲了安全起見,定義你需要的所有轉換,你可能會沒事的。

接下來,將此attribute與您的字符串鍵一起存儲在地圖中(注意:由於缺省值不安全,您必須實現默認的ctor/copy ctor/assign op等等)。如果你不能被後者困擾,在地圖上存儲一個智能指針,例如

std::map<std::string, boost::shared_ptr<attribute> > attributes; 

現在您的界面應該接受密鑰並返回attribute,例如,

attribute const& get(std::string const& some_key) 
{ 
    map<>::iterator it = attributes.find(some_key); 
    return *it->second; 
} 

bool bv = get(some_key); // automatically converted to bool (if lexical_cast doesn't throw)