Как получить enum из boost :: property_tree?

Как получить перечисление от boost::property_tree?

Это мой «нерабочий» пример.

config.xml

<root>
<fooEnum>EMISSION::EMIT1</fooEnum>
<fooDouble>42</fooDouble>
</root>

main.cpp

#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>

int main()
{
enum class EMISSION { EMIT1, EMIT2 } ;
enum EMISSION myEmission;

//Initialize the XML file into property_tree
boost::property_tree::ptree pt;
read_xml("config.xml", pt);

//test enum (SUCCESS)
myEmission = EMISSION::EMIT1;
std::cout << (myEmission == EMISSION::EMIT1) << "\n";

//test basic ptree interpreting capability (SUCCESS)
const double fooDouble = pt.get<double>("root.fooDouble");
std::cout << fooDouble << "\n";

//read from enum from ptree and assign (FAILURE)
myEmission = pt.get<enum EMISSION>( "root.fooEnum" );
std::cout << (myEmission == EMISSION::EMIT1) << "\n";

return 0;
}

Компилировать вывод

/usr/include/boost/property_tree/stream_translator.hpp:36:15:
error: cannot bind 'std::basic_istream<char>' lvalue to
'std::basic_istream<char>&&'

/usr/include/c++/4.8/istream:872:5: error:
initializing argument 1 of 'std::basic_istream<_CharT,
_Traits>& std::operator>
(std::basic_istream<_CharT, _Traits>&&, _Tp&)
[with _CharT = char; _Traits = std::char_traits<char>;
_Tp = main()::EMISSION]'

4

Решение

Имя перечисления в C ++ является символом, а не строкой. Невозможно отобразить строку и значение перечисления, если вы не предоставите это сопоставление самостоятельно, написав такой метод, как:

EMISSION emission_to_string(const std::string& name)
{
if ( name == "EMISSION::EMIT1")
{
return EMISSION::EMIT1;
}
... etc
}

Затем вы получите значение в виде строки из property_tree и примените это отображение.

Есть более хорошие способы реализовать это, которые более элегантно масштабируются со многими значениями enum. Я сделал это, используя boost :: bimap, чтобы включить отображение из enum-> string OR из string-> enum, и, конечно, это также дает вам карту вместо глупо большого оператора if. Если вы сделаете это, посмотрите на использование boost :: assign для инициализации статической карты, так как она выглядит чище, чем другие методы.

5

Другие решения

Отображение между строкой и перечислением должно быть сделано вручную. Однако вы можете реализовать переводчик для перечисления, как описано здесь: http://akrzemi1.wordpress.com/2011/07/13/parsing-xml-with-boost/

Имея это, вы можете удобно написать

myEmission = pt.get<EMISSION>("root.fooEnum");
1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector