2011-02-15 17 views
5

Boots's property_tree kütüphanesini kullanıyorum. ptree nesnesinden bir çocuk düğümü almak için bir yol arıyorum, ancak başarısız olursa boş bir ptree döndürün. Ben property_tree/örneklerle/empty_ptree_trick.cpp güzel bir örnek geldi: tam olarak neye ihtiyacım yoknerede boost property_tree :: empty_ptree?

void process_settings(const std::string &filename) 
{ 
    ptree pt; 
    read_info(filename, pt);  
    const ptree &settings = pt.get_child("settings", empty_ptree<ptree>()); 
    std::cout << "\n Processing " << filename << std::endl; 
    std::cout << "  Setting 1 is " << settings.get("setting1", 0) << std::endl; 
    std::cout << "  Setting 2 is " << settings.get("setting2", 0.0) << std::endl; 
    std::cout << "  Setting 3 is " << settings.get("setting3", "default") <<  std::endl; 
} 

. Sorun, derleyicinin empty_ptree() işlevinin boost:property_tree üyesi olmadığından şikayet etmesidir. empty_ptree()'un nerede olduğu hakkında bir fikir var mı?

VS2010'da 1.44 desteğini kullanıyorum.

cevap

1

Bu soruya cevap vermeye çalışmak için tam bir gün patlattım!

Bu benim çözümümdü. Öncelikle, bunları hemen başlatmanız gerektiğinden, işaretçiler kullandım ve referans olarak kullanmıyorum. Sonra sadece istisna yakaladım ve yeni bir ptree ekledim.

using namespace boost::property_tree; 

ptree r_pt; 
ptree *c_pt; 

read_xml("file.xml" , r_pt); 

try { 
    c_pt = &(r_pt.get_child("example")); 
} 
catch (ptree_bad_path) { 
    c_pt = &(r_pt.put_child("example", ptree())); 
} 

std::cout << "Setting 1 is " << c_pt.get("setting1", 0) << std::endl; 

Toplayabildiğim kadarıyla, boost :: isteğe bağlı türünü kullanmamızı bekliyoruz. Ama ben sadece bir acemi değilim ..

DÜZENLEME Sadece empty_ptree < uygulanmasını bulundu>.

template<class Ptree> 
    inline const Ptree &empty_ptree() 
    { 
     static Ptree pt; 
     return pt; 
    } 

Sadece senin kodu ekleyin ve empty_ptree_trick.cpp açıklandığı gibi kullanabilirsiniz düşünüyorum, ama ben onun aslında yapılması gerekiyordu öğrenmek artık e kadar benim çözüm ile yapışmasını ediyorum.

+0

@expelleboy - çaba için teşekkürler :-). Bununla birlikte, önerilen kodunuzla ilgili birkaç sorun vardır: 1) 'read_xml' de atabilir - böylece 'try' bloğuna koymak isteyebilirsiniz. 2) get_child tarafından döndürülen ptree'nin ömrünün ne olduğundan emin değilim, ancak, destekleme içindeki örnekler her zaman sonucu <> alsın ve asla adreslerini alamaz. Sarkan bir işaretçi ile sonuçlanabilir. 3) 'try-catch' komutunu atlayabilirsiniz. <> (Catch bloğunuzda kullanılan) isteğe bağlı sürümü, asla atmaz. 4) empty_ptree'ye bir referansı oluşturmaktan daha fazla vermektir. – bavaza

+0

@bavaza np. Aslında bu sorunlarla uğraştığım bir sınıf (xml_branch kodumda) oluşturarak, yalnızca xml_branch'i miras alan bir sınıf içinde veya bir ptree'ye bir işaretçi oluşturmak için beni zorluyordu. Kök sınıf daha sonra gerçek ptree ve işaretçisine sahiptir. Sonra kök, üye xml_branch'sinin başlatılması üzerine ortaya çıkan tüm istisnaları işler. Maalesef size tam kaynağı gösteremiyorum, ancak bunu yapmanın oldukça zarif bir yolunu söyleyebilirim. – expelledboy

+0

Maalesef "şube tüm istisnaları işliyor ..." demek istemiştim, ama yorumumu düzenleyemiyorum .. – expelledboy