Search code examples
c++c++20metaprogrammingconstexprcompile-time

Initialize member array at compile time


Is it possible to initialize the idx value of the array_object at compile time such that member_array[0].idx = 0; member_array[1].idx = 1; ... member_array[array_size-1].idx = array_size-1. The value member of every array_object should be initialized with an empty string literal.

struct my_class {
    struct array_object {
        int idx;
        std::string value{};
    };
    static constexpr size_t array_size = /* some compile time constant*/;

    std::array<array_object, array_size> member_array = /* default initialize where idx of each array_object is +1 of the preceeding array_object
                                                        and the first array_object idx is 0 ; array_object value always initialized to empty string*/;
};

Solution

  • It is possible if you make you inner struct constexpr constructible and constexpr copyable.

    UPD: Apparently, it doesn't work on GCC. However, it works on Clang and MSVC. godbolt

    // It is compile time constant that
    // copied into field value.
    template <typename Item, size_t Count>
    inline constexpr std::array<Item, Count> cMemberInit = []() {
      std::array<Item, Count> res;
      for (size_t i = 0; i < Count; ++i) {
        res[i].idx = i;
      }
      return res;
    }();
    
    struct my_class {
      struct array_object {
        int idx{};
        std::string value{};
        constexpr array_object() = default;
        constexpr array_object(const array_object&) = default;
      };
      static constexpr size_t array_size = 7;
      std::array<array_object, array_size> member_array =
          cMemberInit<array_object, array_size>;
    };