将enum与字符串变量一起使用

时间:2010-02-02 17:17:48

标签: c++ enums

我正在尝试做这样的事情,

enum Data_Property
{
 NAME,
 DATETIME,
 TYPE,
};

struct Item_properties
{
  char* Name;
  char* DateTime;
  int Type;  
};

int main() {  
std::string data = "/Name Item_Name /DATETIME [TimeStamp] /TYPE [Integer value]";
std::list <std::string> known_properties;

known_properties.push_back("/Name");
known_properties.push_back("/DATETIME");
known_properties.push_back("/TYPE");

Item_properties item_p = extract_properties(data); //I use a function to get properties
                                                   //in a structure.

//here I want to use a switch-case statement to get the property by enum value
}

我需要知道有什么方法可以让它变得简单吗?或者我如何将(/ NAME / DATETIME / TYPE)等属性键与枚举结合使用,并避免使用std :: list即known_properties?

3 个答案:

答案 0 :(得分:3)

据我所知,C ++枚举中没有任何内容与C#enum属性相似。我可能错了。

鉴于此,我建议使用地图将data属性映射到item属性。你应该只需要构建一次这个地图。您还可以将字符串表示关联到项目和数据属性。这样可以更容易地构建项目属性对象。我认为列表不是这项任务的理想数据结构。

答案 1 :(得分:2)

首先,让我说总有另一种选择,这是我的哲学之一。

让我们来看看大图片。您正在尝试从字符串中读取是基准的容器。在面向对象的术语中, Item 希望每个数据从字符串加载自己的数据。 不需要知道如何加载数据,因为它可以从每个数据请求。

您的基准实际上比C ++简单POD类型更复杂和更智能。 (简单的POD类型没有字段名称。)因此,您需要创建表示这些的类(或封装额外的复杂性)。相信我,从长远来看,这会更好。

以下是重构 Name成员的简单示例:

struct Name_Field
{
  std::string  value;  // Change your habits to prefer std:string to char *
  void load_from(const std::string& text,
                 const std::string::size_type& starting_position = 0)
  {
     value.clear();
     std::string::size_type position = 0;
     position = text.find("/Name", starting_position);
     if (position != std::string::npos) // the field name was found.
     {
         // Skip the next space
         ++position;

         // Check for end of text
         if (position < text.length())
         {
             std::string::size_t   end_position;
             end_position = text.find_first_not_of(" ", position);
             if (end_position != std::string::npos)
             {
                 value = text.substr(position, end_position - position);
             }
          }
      }
};

您现在可以在类中添加load_from

struct Item
{
    Name_Field   Name;
    char *       DateTime;
    char *       Type;
    void load_from(const std::string& text)
    {
        std::string::size_t  position = 0;

        // Notice, the Name member is responsible for load its data,
        //    relieving Item class from knowing how to do it.
        Name.load_from(text, position);
    }
};

加载项目:

Item new_item;
new_item.load_from(data);

在重构时,请注意常用方法。例如,您可能希望将Name_FieldDateTime_Field之间的常用方法放入基础(父)类Field_Base中。这将简化您的代码和设计,并支持可重用性。

答案 2 :(得分:1)

你看过Boost :: program_options吗?这是一些示例代码:

#include "boost\program_options\parsers.hpp"
#include "boost\program_options\variables_map.hpp"
#include <iostream>
using std::cout;
using std::endl;

namespace po = boost::program_options;

int _tmain(int argc, _TCHAR* argv[])
{

    po::options_description desc("Allowed options");
    string taskName;
    desc.add_options()
        ("help", "produce help message")
        ("TaskName", po::value<string>(&taskName), "The project's prefix")
    ;

    po::variables_map vm;
    po::store(po::parse_command_line(argc, argv, desc), vm);
    po::notify(vm);    

    if (vm.count("help")) {
        cout << desc << endl;
        return 1;
    }
    if (!vm.count("TaskName"))
    {
        cout << "Use \"DOTaskTests.exe --help\" for command line options" << endl;
        return 1;
    }
 }