Есть ли шаблон (или нечто похожее) для имён полей структуры?
Допустим у меня есть код на поиск элемента в массиве структур. Поиск может осуществляться по разным полям структуры. Соответственно нужно отдельно прописывать эти поля каждый раз и получается не очень красиво. Может есть какой-то способ обобщить?
if (key == 1)
{
for (int i = 0; i < size; i++)
if (!strcmp(query,p[i].name))
return i;
return -1;
}
else if (key == 2)
{
for (int i = 0; i < size; i++)
if (!strcmp(query, p[i].surname))
return i;
return -1;
}
else if (key == 3)
{
for (int i = 0; i < size; i++)
if (!strcmp(query,p[i].zodiak))
return i;
return -1;
}
Ответы (5 шт):
Автор решения: Harry
→ Ссылка
Извините, что ответом, это скорее комментарий, но иначе не влезет.
А почему не сделать
for (int i = 0; i < size; i++)
if (!strcmp(query,
key == 1 ? p[i].name :
key == 2 ? p[i].surname :
key == 3 ? p[i].zodiak : nullptr ))
return i;
return -1;
Ну, nullptr, понятно, надо заменить или проверять key заранее, но идея, думаю, понятна?
Автор решения: Artyomka
→ Ссылка
Решение с оператором switch уже выглядит попроще, но далеко до идеала.
for (int i = 0; i < size; ++i)
{
switch (key)
{
case 1:
if (!strcmp(query, p[i].name)) return i;
break;
case 2:
if (!strcmp(query, p[i].surname)) return i;
break;
case 3:
if (!strcmp(query, p[i].zodiak)) return i;
break;
default:
return -1;
}
}
return -1;
Автор решения: Chorkov
→ Ссылка
Здесь просятся указатели на члены класса.
struct Foo // предполагаемая струкутура данных
{
char * name;
char * surname;
char * zodiak;
// ...
};
typedef char* (Foo::* fooMemderPtr);
// таблица номеров полей структуры
static const std::map< int, fooMemderPtr > fooMembersList={
{ 1, & Foo::name },
{ 2, & Foo::surname },
{ 3, & Foo::zodiak},
};
...
fooMemderPtr memberPtr = fooMembersList.at(key);
for (int i = 0; i < size; i++)
if (!strcmp(query, p[i].*memberPtr))
return i;
return -1;
Автор решения: LShadow77
→ Ссылка
Ну я бы, например, так это реализовал:
#define NUM_KEYS 3
struct Foo // предполагаемая струкутура данных
{
union
{
char* keys[NUM_KEYS];
struct
{
char* name;
char* surname;
char* zodiak;
};
};
// ...
};
/*
* ......................
*/
assert ((key>=1) && (key<=NUM_KEYS));
--key;
for (int i = 0; i < size; i++)
if (!strcmp(query,p[i].keys[key])) return i;
return -1;
Автор решения: AR Hovsepyan
→ Ссылка
Если на С++, то все проще. Например:
class Names {
const std::array<std::string_view, 3> p;
public:
constexpr Names(const std::array<std::string_view, 3>& names)
noexcept : p(names){}
[[nodiscard]] bool
find_name(std::string_view query,
const size_t key) const noexcept
{
if (!key || key > 3)
return false;
return query == p[key - 1];
}
//...
};
int main()
{
constexpr Names n({ "one", "two", "three" });
cout << n.find_name("two", 1);
return 0;
}