简体   繁体   English

如何从boost :: property_tree获取枚举?

[英]How to get enum from boost::property_tree?

How do I get an enum from a boost::property_tree ? 如何从boost::property_tree获取枚举?

This is my "non-working" example. 这是我的“不工作”的例子。

config.xml config.xml中

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

main.cpp 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;
}

Compile Output 编译输出

/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]'

The name of an enum in C++ is a symbol, not a string. C ++中枚举的名称是符号,而不是字符串。 There isn't a way to map between a string and an enum value unless you provide that mapping yourself by writing a method such as: 没有办法在字符串和枚举值之间进行映射,除非您通过编写如下方法来自己提供映射:

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

You would then get the value as a string from the property_tree and apply this mapping. 然后,您将从property_tree获取值作为字符串并应用此映射。

There are nicer ways to implement this which scale more elegantly with many enum values. 有更好的方法来实现它,使用许多枚举值更优雅地扩展。 I have done this using boost::bimap to enable a mapping from enum->string OR from string->enum, and of course this also gives you a map instead of a silly big if statement. 我已经使用boost :: bimap来实现这一点,以便从enum-> string或string-> enum启用映射,当然这也为您提供了一个映射而不是一个愚蠢的大if语句。 If you do this, look into using boost::assign to initialise your static map, as it looks cleaner than other methods. 如果你这样做,请查看使用boost :: assign初始化静态地图,因为它看起来比其他方法更清晰。

The mapping between string and enum has to be done by hand. 字符串和枚举之间的映射必须手工完成。 However, you can implement a translator for the enum as descibed here: http://akrzemi1.wordpress.com/2011/07/13/parsing-xml-with-boost/ 但是,您可以在此处实现enum的翻译器: http//akrzemi1.wordpress.com/2011/07/13/parsing-xml-with-boost/

Having this, you can conveniently write 有了这个,你可以方便地写

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM