考虑以下示例:
struct MyStruct {
int a;
int b;
};
我可以通过这样做使用宏来从结构的实例设置成员:
#define setVar(x,y) instance.x = y
然后我可以说任何功能:
setVar(a, 4)
如何将字符串作为字符串发送到宏?这也可能吗?
setVar("a", 4)
编辑:有一堆预定义的结构,其成员都是double类型。我只知道传入的XML配置文件使用的是什么结构。解析后,我有一堆字符串,它们是需要设置的所有数据成员和值的列表。我需要使用此列表为结构中的每个成员设置值。
答案 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);
}
答案 1 :(得分: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;
}
答案 2 :(得分:0)
可能不是你正在寻找的东西,但宏等的替代解决方案..只是一些封装和OO设计。您可以稍后将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() ) ) );