Рассмотрим эту упрощенную и очень конкретную реализацию рекурсивного варианта поверх std::variant:
#include <map>
#include <variant>
struct recursive_tag;
template <typename...>
struct RecursiveVariant;
template <>
struct RecursiveVariant<int, std::map<int, recursive_tag>>
    : std::variant<int, std::map<int, RecursiveVariant<int, std::map<int, recursive_tag>>>>
{
    using underlying = std::variant<int,
          std::map<int, RecursiveVariant<int, std::map<int, recursive_tag>>>>;
    using underlying::underlying;
};
int main() {
    RecursiveVariant<int, std::map<int, recursive_tag>> rv; 
}
  Это не удается скомпилировать на gcc 7/8 из-за попытки создать экземпляр std::pair<const int, recursive_tag>, который сам терпит неудачу, потому что recursive_tag является неполным типом.
 Но ничто в вызове-стеке компилятора не указывает мне, почему нужно создать экземпляр std::pair<const int, recursive_tag>. Верхняя строка:
вариант: 252: 48: требуется от '
void std::__detail::__variant::__erased_dtor(_Variant&&) [with _Variant = const std::__detail::__variant::_Variant_storage<false, int, std::map<int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > >, std::less<int>, std::allocator<std::pair<const int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > > > > > >&; long unsigned int _Np = 0]void std::__detail::__variant::__erased_dtor(_Variant&&) [with _Variant = const std::__detail::__variant::_Variant_storage<false, int, std::map<int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > >, std::less<int>, std::allocator<std::pair<const int, RecursiveVariant<int, std::map<int, recursive_tag, std::less<int>, std::allocator<std::pair<const int, recursive_tag> > > > > > > >&; long unsigned int _Np = 0]
указывая на:
249   template<typename _Variant, size_t _Np>
250     void
251     __erased_dtor(_Variant&& __v)
252     { std::_Destroy(std::__addressof(__get<_Np>(__v))); }
  В то время как в нем написана map<int, recursive_tag> типа map<int, recursive_tag>, фактический тип map который должен быть создан, - map<int, RecursiveVariant<int, map<int, recursive_tag>>>..., который должен требовать только создания pair<const int, RecursiveVariant<...>>.
 Простое выполнение recursive_tag (т.е. добавлением {}) устраняет проблему. Но с чего начинается эта проблема?