Мне нужно начать с кода, потому что я не уверен, какую терминологию использовать. Допустим, у меня есть следующий код:назначить член на основе значения строки
class Node
{
public:
void Parse(rapidxml::xml_node<> *node)
{
for (rapidxml::xml_attribute<> *attr = node->first_attribute();
attr;
attr = attr->next_attribute())
{
std::stringstream converter;
converter << attr->value();
if(!strcmp(attr->name(), "x")) converter >> x;
else if(!strcmp(attr->name(),"y")) converter >> y;
else if(!strcmp(attr->name(), "z")) converter >> z;
}
}
private:
float x;
float y;
float z;
};
То, что я терпеть не могу это повторение, если (зЬгстр (attr-> имя(), «х»)!) Преобразовательной >> х; Я чувствую, что это склонность к ошибкам и монотонность, но я не могу придумать другой способ сопоставить строковое значение с назначением члена. Каковы некоторые другие подходы, которые можно предпринять, чтобы избежать такого кода? Единственный возможный альтернативный я мог думать только о том, чтобы использовать HashMap, но сталкивается с проблемами с обратных вызовов
Это лучшее, что я мог бы с, но это не так гибок, как я хотел бы:
class Node
{
Node() : x(0.0f), y(0.0f), z(0.0f)
{
assignmentMap["x"] = &x;
assignmentMap["y"] = &y;
assignmentMap["z"] = &z;
}
public:
void Parse(rapidxml::xml_node<> *node)
{
for (rapidxml::xml_attribute<> *attr = node->first_attribute();
attr;
attr = attr->next_attribute())
{
map<std::string, float*>::iterator member = assignmentMap.find(attr->name());
//check for a pre-existing entry
if(member == assignmentMap.end()) continue;
std::stringstream converter;
converter << attr->value();
converter >> *(member->second);
}
}
private:
float x;
float y;
float z;
std::map<std::string, float*> assignmentMap;
};
Для разметки кода выберите код и нажмите кнопку «101» в редакторе в следующий раз. –
Ой, как это делается, спасибо, noscript блокировал googelapi, и я всегда был в замешательстве! – Apeiron
В вашем втором решении есть ошибка. 'std :: map :: operator []' создаст запись с указанным ключом, если ее еще нет, поэтому, если ваш код встречается с именем атрибута, который отсутствует на карте, он попытается разыменовать недавно созданный указатель (который будет инициализирован NULL, я уверен). Вы можете избежать этого, используя 'iter = assignMap.find (attr-> name()); if (iter! = assignMap.end()) converter >> * (iter-> second) '. –