Вопрос по c++ – Как получить член структуры со строкой, используя Macros C ++

5

Рассмотрим следующий пример:

struct MyStruct {
    int a;
    int b;
};

Я могу использовать макросы для установки члена из экземпляра структуры, выполнив это:

#define setVar(x,y) instance.x = y

тогда в любой функции я могу сказать:

setVar(a, 4)

Как я могу отправить в качестве строки в макрос? Это тоже возможно?

setVar("a", 4)

РЕДАКТИРОВАТЬ: Есть куча предопределенных структур с членами типа double. Я знаю только, какую структуру я использую в файле конфигурации XML, который передается. После анализа у меня есть набор строк, представляющих собой список всех элементов данных и значений, которые необходимо установить. Мне нужно использовать этот список, чтобы установить значения для каждого из членов в структуре.

Вам нужно объяснить свою реальную проблему, чтобы мы могли дать вам реальное решение. Martin York
Почему вы хотите использовать такие макросы? crashmstr
У меня возникают боли в груди, и я пытаюсь поддержать этот код. John Dibling
Нет, есть куча предопределенных структур, из которых мне нужен доступ к данным, и я могу получить к ним доступ только с помощью файла XML со списком его переменных. Есть ли другой способ сделать это? Кроме того, x всегда будет иметь тип double ulu5
Вы хотите программно во время выполнения создать имена полей? Это невозможно. liori

Ваш Ответ

3   ответа
0

но мог бы дать вам несколько идей, надеюсь, это поможет. Основным трюком здесь также является использование союзов.

struct MyStruct
{
int a;
double b;

MyStruct() 
    : a(0), b(0) {}
};

MyStruct instance;

union value 
{
    long value_a;
    double value_d;
} myvalue;


void blah_a(value v)
{
    instance.a = v.value_a;
}

void blah_b(value v)
{
    instance.b = v.value_d;
}

struct 
{
    (void)(*fn)(value);
    const char* key;
}

lookup_table[] = 
{
    { &blah_a, "a" },
    { &blah_b, "b" }
};

void setVar(const char* c, value v)
{
     for (int i = 0; lookup_table[i].fn; i++)
          if (c == lookup_table[i].key)
               (*(lookup_table[i].fn))(v);
}

int main(int argc, char* argv[])
{
    value v;
    v.value_a = 6;
    setVar("a", v);
    return 0;
}
7

если вы определяете саму структуру с помощью некоторого макроса, например:

#define MY_STRUCT_STRUCTURE FIELD(a) FIELD(b) FIELD(d) FIELD(e) FIELD(f)

struct MyStruct {

# define FIELD(name) int name;
    MY_STRUCT_STRUCTURE
# undef FIELD

  bool setVar(char* fieldname, int val)
  {
#   define FIELD(name) if(strcmp(#name,fieldname)==0){name=val; return true;};
    MY_STRUCT_STRUCTURE
#   undef FIELD
    return false; // name not found
  }
};


int main()
{
  MyStruct s;
  s.setVar("a",1);
  s.setVar("b",2);
  s.setVar("f",100);
}
Error: User Rate Limit Exceeded
Error: User Rate Limit Exceeded ulu5
0

это не то, что вы ищете, а альтернативное решение для макросов и т. Д. - это просто инкапсуляция и дизайн ОО. Позже вы можете изменить класс Field на шаблон, и вы сможете представлять что угодно в принципе.

Вы можете создать класс

class Field
{
public:
    Field(const std::string& name, const std::string& type);
    virtual ~Field(void);
    std::string toString() const;
    std::string getName() const;
    int getValue() const { return value };
private:
    std::string name;
    std::string type;
    int value;
};

А потом класс структуры

#pragma once
#include <boost/ptr_container/ptr_deque.hpp>
#include <string>

class Field;

class MyStructure
{
public:
    typedef boost::ptr_deque<Field> FieldList;
    typedef FieldList::iterator FieldListIter;
    typedef FieldList::auto_type AutoField;

    MyStructure(void);
    MyStructure(const std::string& name);
    virtual ~MyStructure(void);

    void setName(const std::string& name);
    std::string getName() const;
    void addField( std::auto_ptr<Field> field );
    std::string getFieldValue( const std::string& name ) const;
    MyStructure::AutoField removeField( const std::string& name );
    std::string toString(void) const;

private:
    std::string struct_name;
    FieldList fields;
};

А потом использовать это:

auto_ptr<MySructure> struct_a(new MySructure("StructName1",0) );
struct_a->addField( auto_ptr<Field> ( new Field( "Field1",    1 ) ) );
struct_a->addField( auto_ptr<Field> ( new Field( var_str1,    2) ) );
struct_a->addField( auto_ptr<Field> ( new Field( getName(),   getVal() ) ) );

Похожие вопросы