简体   繁体   中英

Is there a way to count member variable of a class in compile time?

What I want to do is to check member variable count of a class, as some newbie might write too much member variable to read. Is there some way to get it?

We did do code reviews, but a static_assert(GET_MEM_VAR_COUNT(ClassA) < 10) might be more straight and clear.

Until we get reflection, you are stuck using another tool to check the number of members in a class.

We have a few crude ways to get reflection now, with many limitations. If you only have a data struct, then you can use Boost Fusion to define your class such that you can assert on its size, for example:

#include <string>

#include <boost/fusion/include/define_struct.hpp>
#include "boost/mpl/size.hpp"

BOOST_FUSION_DEFINE_STRUCT(
    (my_namespace), my_class,
    (std::string, member1)
    (int, member2)
    (int, member3)
    (double, member4)
//Uncomment me to trigger assert  (double, member5)
)

static_assert(boost::mpl::size<my_namespace::my_class>::type::value < 5, "Classes must have fewer than 5 members");

Demo

There is a way for aggregate types.

Example:

#include <iostream>
#include <utility>

namespace impl {
    struct any_type {
        template<typename T>
        constexpr operator T();
    };

    template <class T, class... Ts>
    decltype(void(T{ { std::declval<Ts>() }... }), std::true_type{}) test_is_braces_constructible(std::size_t);

    template <class, class...>
    std::false_type test_is_braces_constructible(...);

    template<std::size_t N, class T, class... Ts>
    struct sizeof_struct : public std::conditional_t<
        decltype(test_is_braces_constructible<T, Ts...>(0))::value,
        sizeof_struct<N + 1, T, any_type, Ts...>,
        std::integral_constant<std::size_t, N>
    > {};
}

template<typename T, typename = std::enable_if_t<std::is_aggregate_v<T>>>
using sizeof_struct = typename impl::sizeof_struct<0, T, impl::any_type>;

template<typename T>
constexpr inline auto sizeof_struct_v = sizeof_struct<T>::value;

struct Foo {
  int i;
  float f;
  double d;
};

int main() {
  std::cout << sizeof_struct_v<Foo>; //outputs 3

  return 0;
}

This was made for C++17 but can be converted to be used in C++14 and even C++11.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM