2017-08-26 45 views
1

我想定義一個地圖,它將一個字符串作爲關鍵字,但該值將是一個以字符串作爲關鍵字的地圖,但該值將會是一個地圖類似的性質......,最終鏈中的最後一張地圖將是從字符串到字符串的映射。C++:定義具有遞歸屬性值的地圖

我想實現標記的JSON數據結構的值。

爲了說明,這裏是我能想出的代碼段:

typedef map<string, string> str2str; 
typedef map<string, str2str> str2str2str; 
... 
typedef map<string, str2map_or_str> str2map_or_str; 

是什麼在C++中慣用的方法呢?

+0

看看https://stackoverflow.com/questions/23601686/shorthand-syntax-for-c-map-in-map。也許這就是你要找的。 –

+0

謝謝,但該解決方案似乎假定地圖的已知水平。我不知道,它需要多少級別。 –

回答

1

一個簡單的方法是使用structstring和遞歸map

struct ParseData; 
using MapValue = std::map<std::string, ParseData>; 

struct ParseData 
{ 
    std::string string_value; 
    MapValue map_value; 
}; 

然後,您可以使用一個ParseData對象或MapValue對象捕捉分析數據。

+0

是否需要完成「std :: map」的值類型? boost通過許多循環來完成遞歸定義。否則,這將是明顯的做法。 – StoryTeller

+0

@StoryTeller,我不確定。似乎在https://ideone.com/gmTBWB上工作。 –

+0

@StoryTeller,推動推動,可以使用'ParseData'中的'MapValue *'作爲'map_value'。 –

3

更習慣的解決方案IMO是使用允許遞歸類型定義的庫。你基本上需要一棵樹,每個葉子只是一個字符串。值得慶幸的是,boost::variant允許您定義遞歸變種:

using map_data = boost::make_recursive_variant< 
        std::string, 
        std::map< 
        std::string, 
        boost::recursive_variant_ 
        > 
       >::type; 

這是一個實用的功能元定義了新的變量類型。它將是一個簡單的std::stringstd::mapstd::stringmap_data(標有特殊標記boost::recursive_variant_)。就是這樣。沒有深度限制。

那麼你json_data類型只是以下別名:

using json_data = std::map<std::string, map_data>; 

你可以看到它在直播here。唯一需要注意的是,您需要重寫代碼才能使用boost::variant訪問者模式。但這不是一件很難的練習。我敢說,定義的遞歸性使得邏輯幾乎可以自行編寫。