Как узнать количество полей в структуре?
struct A {
int a,b; // 2 поля
}
struct B {
float a,b,c; // 3 поля
}
В общем случае это невозможно.
В C++23 должны добавить рефлексию, с помощью которой это можно будет делать, но до тех пор придется довольствоваться разными сомнительными хаками.
Есть несколько решений для частных случаев:
Если у вас все поля в структуре одного типа, и вы знаете, какого именно, то, как предложил @ARHovsepyan, можно поделить размер структуры на размер одного ее члена:
int main()
{
std::cout << sizeof(A) / sizeof(int) << '\n';
std::cout << sizeof(B) / sizeof(float) << '\n';
}
Хотя, ЕМНИП, компиляторам разрешается добавлять в структуры сколько угодно неиспользуемых байт (padding) между и после полей, чтобы расположить их в памяти определенным образом (из-за чего этот трюк перестал бы работать), я еще не видел ни одного компилятора, который действительно делал бы это для структур с полями одного типа.
Есть еще один вариант, более универсальный.
Если вы не создали для вашей структуры ни одного конструктора, и в структуре нет полей-массивов, то можно сделать вот что:
#include <cstddef>
#include <iostream>
#include <experimental/type_traits>
#include <utility>
struct stub
{
template <typename T> operator T() const;
};
template <typename T, typename ...P>
using detect_brace_constructible = decltype(T{std::declval<P>()...});
template <typename T, std::size_t ...I>
constexpr bool constructible_with_stubs(std::index_sequence<I...>)
{
return std::experimental::is_detected_v<
detect_brace_constructible, T, std::enable_if_t<1 || I, stub>...
>;
}
template <typename T, std::size_t ...I>
constexpr int field_count_impl(std::index_sequence<I...>)
{
int ret = -1;
((void(ret = I), constructible_with_stubs<T>(std::make_index_sequence<I>{})) && ...);
return ret-1;
}
template <typename T, std::size_t MaxFieldCount = 32>
inline constexpr int field_count =
field_count_impl<T>(std::make_index_sequence<MaxFieldCount+1>{});
struct A
{
int a,b;
};
struct B
{
float a,b,c;
};
int main()
{
std::cout << field_count<A> << '\n'; // 2
std::cout << field_count<B> << '\n'; // 3
}
Этот шаблон последовательно пробует конструировать структуру с возрастающим количеством аргументов:
A{}
A{stub{}}
A{stub{}, stub{}}
A{stub{}, stub{}, stub{}}
...
Где stub{}
- это заглушка, которая может быть преобразована в любой нужный тип.
Такое конструирование будет успешно, пока заглушек столько же, сколько полей в структуре, или меньше. Если заглушек будет больше - будет ошибка. Мы эту ошибку обнаруживаем с помощью SFINAE и возвращаем число заглушек, при котором ошибки не было.
Но если в структуре есть массив, то такой шаблон ошибочно посчитает каждый элемент массива за отдельное поле структуры.
В добавление к существующему ответу: есть библиотека Precise and Flat Reflection, в которой реализован требуемый функционал. Там же можно посмотреть как всё сделано, если интересна реализация.
Кофе для программистов: как напиток влияет на продуктивность кодеров?
Рекламные вывески: как привлечь внимание и увеличить продажи
Стратегії та тренди в SMM - Технології, що формують майбутнє сьогодні
Выделенный сервер, что это, для чего нужен и какие характеристики важны?
Современные решения для бизнеса: как облачные и виртуальные технологии меняют рынок
1) Как сделать расширенную цветную подсветку синтаксиса кода в VS2010 для C++? Может, расширение какое-нибудьНапример, как в ReSharper C++ (имена методов...