2012-09-13 39 views
2

我想存儲一個boost ::任何類型到一個boost屬性樹。這裏有一些可運行的例子:在boost :: property_tree中添加boost :: any可能嗎?

#include <string> 
#include <vector> 
#include <sstream> 
#include <iostream> 
#include <sys/types.h> 
#include <boost/any.hpp> 
#include <boost/property_tree/ptree.hpp> 
#include <boost/property_tree/json_parser.hpp> 

int main() 
{ 
    boost::property_tree::ptree pTree_Root; 
    pTree_Root.put("sigRoot.property1", "value1"); 
    pTree_Root.put("sigRoot.property2", "value2"); 
    pTree_Root.put("sigRoot.property3", "value3"); 

    std::vector<std::string> vecString; 

    for(int i = 0; i <= 5; i++) { 
     vecString.push_back("somestring"); 
    } 

    boost::any anyVar = vecString; 

    pTree_Root.put("sigRoot.property4", anyVar); 

    std::stringstream ss; 
    boost::property_tree::json_parser::write_json(ss, pTree_Root); 
    std::string jsonString = ss.str(); 

    jsonString.erase(std::remove(jsonString.begin(), jsonString.end(), '\n'), jsonString.end()); 

    std::cout << jsonString << std::endl; 

    return 0; 
} 

這不起作用,可能出於同樣的原因boost :: any不可序列化。但我看到我被允許查詢anyVar.type(),但我不知道可以用它做什麼。是否有可能以某種方式使用auto或其他東西來將數據添加到屬性樹中,而無需在此處顯式編碼固定數量的已知類型? C++ 11/C++ 0x方法也是受歡迎的。

這是我的錯誤:

In file included from /usr/include/boost/property_tree/ptree.hpp:17:0, 
       from pTreeTest.cpp:8: 


/usr/include/boost/property_tree/stream_translator.hpp: In static member function ‘static void boost::property_tree::customize_stream<Ch, Traits, E, Enabler>::insert(std::basic_ostream<_Ch, _Tr>&, const E&) [with Ch = char, Traits = std::char_traits<char>, E = boost::any, Enabler = void]’: 
/usr/include/boost/property_tree/stream_translator.hpp:199:13: instantiated from ‘boost::optional<std::basic_string<Ch, Traits, Alloc> > boost::property_tree::stream_translator<Ch, Traits, Alloc, E>::put_value(const E&) [with Ch = char, Traits = std::char_traits<char>, Alloc = std::allocator<char>, E = boost::any]’ 
/usr/include/boost/property_tree/detail/ptree_implementation.hpp:795:54: instantiated from ‘void boost::property_tree::basic_ptree<Key, Data, KeyCompare>::put_value(const Type&, Translator) [with Type = boost::any, Translator = boost::property_tree::stream_translator<char, std::char_traits<char>, std::allocator<char>, boost::any>, Key = std::basic_string<char>, Data = std::basic_string<char>, KeyCompare = std::less<std::basic_string<char> >]’ 
/usr/include/boost/property_tree/detail/ptree_implementation.hpp:817:13: instantiated from ‘boost::property_tree::basic_ptree<K, D, C>& boost::property_tree::basic_ptree<Key, Data, KeyCompare>::put(const path_type&, const Type&, Translator) [with Type = boost::any, Translator = boost::property_tree::stream_translator<char, std::char_traits<char>, std::allocator<char>, boost::any>, Key = std::basic_string<char>, Data = std::basic_string<char>, KeyCompare = std::less<std::basic_string<char> >, boost::property_tree::basic_ptree<Key, Data, KeyCompare>::path_type = boost::property_tree::string_path<std::basic_string<char>, boost::property_tree::id_translator<std::basic_string<char> > >]’ 
/usr/include/boost/property_tree/detail/ptree_implementation.hpp:832:72: instantiated from ‘boost::property_tree::basic_ptree<K, D, C>& boost::property_tree::basic_ptree<Key, Data, KeyCompare>::put(const path_type&, const Type&) [with Type = boost::any, Key = std::basic_string<char>, Data = std::basic_string<char>, KeyCompare = std::less<std::basic_string<char> >, boost::property_tree::basic_ptree<Key, Data, KeyCompare>::path_type = boost::property_tree::string_path<std::basic_string<char>, boost::property_tree::id_translator<std::basic_string<char> > >]’ 



pTreeTest.cpp:26:47: instantiated from here 
/usr/include/boost/property_tree/stream_translator.hpp:33:13: error: cannot bind ‘std::basic_ostream<char>’ lvalue to ‘std::basic_ostream<char>&&’ 
/usr/include/c++/4.6/ostream:581:5: error: initializing argument 1 of ‘std::basic_ostream<_CharT, _Traits>& std::operator<<(std::basic_ostream<_CharT, _Traits>&&, const _Tp&) [with _CharT = char, _Traits = std::char_traits<char>, _Tp = boost::any]’ 

回答

5

boost::any沒有operator <<。您不能在property_tree中使用anyanyVar.type()返回std::typeinfo,這個類提供runtime關於類型的信息。

template<typename Type, typename Translator> 
    self_type & put(const path_type & path, const Type & value, Translator tr); 

在給定路徑到所提供的值,轉換爲樹的數據類型設置的節點的值。如果該節點不存在,則創建該節點,包括其所有丟失的父節點。

您可以創建Translator,並把它傳遞給函數的說,因爲ptree是真的basic_ptree<std::string, std::string>您的翻譯應該轉換anystring

翻譯

struct SimpleTranslator 
{ 
public: 
    boost::optional<std::string> put_value(const boost::any& value) 
    { 
     if (value.type() == typeid(std::vector<std::string>)) 
     { 
     std::stringstream ss; 
     std::vector<std::string> vec = boost::any_cast<std::vector<std::string>>(value); 
     std::copy(vec.begin(), vec.end(), std::ostream_iterator<std::string>(ss)); 
     return ss.str(); 
     } 
     return boost::optional<std::string>(); 
    } 
}; 

http://liveworkspace.org/code/275820c1becfb63deda4e4eed8524833

+0

的簡單例子非常感謝你爲這個!但我有個問題。當我決定通過別的東西時,我必須擴展翻譯。我只是在自己挖掘一點點。我看到類似[boost :: spirit :: hold_any](http://www.boost.org/doc/libs/1_50_0/boost/spirit/home/support/detail/hold_any.hpp)。它似乎有stringstream輸出功能。但我不確定如何使用它。有任何想法嗎? –

+0

@SubhamoySengupta hold_any是精神的細節...因此,這樣的事情的使用是不好的,+ +不能輸出與hold_any載體,因爲它使用運算符<<爲T,但矢量沒有運算符<<。 – ForEveR

+0

非常感謝!我想稍等一會兒,然後才標出正確的答案,因爲我只是剛剛發佈了它,但我認爲你所建議的是我必須做的。 –

相關問題