I have an array with items of type variant that I want to iterator over using the generic std::array iterator. Now I want to do the management of the array with my own class array2. However, the variant might also contain an object of type array2 which is instantiated using the variant itself, which means that val is already required as a template parameter.
From a logical standpoint this problem seems solvable: I don't use a data member of type val in array2, this means memory layout of val can be fixed upon definition. However, I would have to forward declare the val-type to use it in the definition of val. Can I do that somehow? Or is there a more idiomatic approach to this problem / a workaround?
I have checked out C++ Forward declare using directive but it doesn't answer my question because it doesn't use recursion (which makes it a lot easier).
#include <variant>
#include <cstddef>
#include <array>
template <typename T, size_t V> struct array2;
template <size_t V>
using val = std::variant<std::monostate, int, array2<val, V>>;
template <typename T, size_t V>
struct array2
{
    using iterator = typename std::array<T, V>::iterator;
    iterator begin_; // array allocation not done in here
    iterator end_;
};
int main() {}
Yields:
<source>:9:54: error: 'val' was not declared in this scope
    9 | using val = std::variant<std::monostate, int, array2<val, V>>;
Update:
Note that array2's size does not depend on the definition of val, except that the using declaration does require it for std::array<val, V> to be complete apparently.
 
    