Вот пример уменьшенного примера, который не требует Boost.Spirit (и, следовательно, компилируется намного быстрее):
#include <iostream>
#include <variant>
struct text { };
typedef std::variant<text> column_variant;
std::ostream& operator<< (std::ostream& os, column_variant const& v) {
std::visit([&os](auto const& e) { os << e; }, v);
return os;
}
int main() {
column_variant v;
std::cout << v;
}
Итак, первый вопрос, который у меня возник, когда я увидел ваш код, на самом деле: как это вообще компилируется? Я ожидал этого, и был удивлен, когда это произошло. И причина, по которой он компилируется, - фактически та же самая причина, по которой вы получаете переполнение стека, которое ...
Что это на самом деле делает?
std::cout << text{};
<ч />
Нет operator<<
взятия text
, верно? Но там - это operator<<
с аргументом, который можно построить из text
: column_variant
! Поскольку ни один из типов в variant
не является независимо потоковым, попытка потоковой передачи любого из них приводит к рекурсивному вызову оператора потока варианта.
Вставьте что-то вроде этого:
std::ostream& operator<<(std::ostream& os, text) {
return os << "text";
}
И больше нет рекурсии.