Доступ к статическим членам дочерних классов

Есть базовый класс:

template<typename S>
class Base
{
    inline static std::vector<double> values_{};
};

При наследовании создается своя копия values_ для каждого типа:

struct A : Base<A>{};
struct B : Base<B>{};
struct C : Base<C>{};

Как сделать перебор (например в цикле) всех values_ во всех дочерних классах? A::values_, B::values_, C::values_ и т.д.?

У меня есть идея сделать один статический array<vector<double>, N> в Base (без CRTP), но не понимаю, как вычислить N. Вводить целочисленный шаблонный параметр нежелательно, хотелось бы, что бы все вычислялось само.


Ответы (1 шт):

Автор решения: HolyBlackCat

Оно?

#include <cstddef>
#include <iostream>
#include <type_traits>
#include <vector>

using Registry = std::vector<std::vector<double> *>;
Registry &getRegistry()
{
    // Должна быть внутри функции чтобы порядок иницализации был всегда правильный.
    static Registry ret;
    return ret;
}

template <typename D>
struct Base
{
    inline static std::vector<double> values_{};

  private:
    // Регистрируем этот класс.
    inline static const std::nullptr_t register_class = []{
        getRegistry().push_back(&values_);
        return nullptr;
    }();
    // Инстанцируем предыдущую переменную.
    inline static constexpr std::integral_constant<const std::nullptr_t *, &register_class> register_class_helper{};
};

struct A : Base<A> {};
struct B : Base<B> {};
struct C : Base<C> {};

int main()
{
    A::values_ = {1,2};
    B::values_ = {3,4,5};

    for (const auto *vec : getRegistry())
    {
        std::cout << "[ ";
        for (double elem : *vec)
            std::cout << elem << ' ';
        std::cout << "]\n";
    }

    // [ 1 2 ]
    // [ 3 4 5 ]
    // [ ]
}
→ Ссылка