0

So I wrote an object that could handle JSON-like content, of which there is a minimal example:

#include <iostream>
#include <vector>
#include <variant> 

struct Array;
struct Value;

struct Array: public std::vector<Value>{
    using std::vector<Value>::vector;
};

struct Value: public std::variant<bool, int, Array>{
    using std::variant<bool, int, Array>::variant;
};

Now I wanted to overload the output stream operator. Here is the code:

std::ostream& operator <<(std::ostream& os, const Value value);
std::ostream& operator <<(std::ostream& os, const Array array);

std::ostream& operator <<(std::ostream& os, const Array array){
    for (auto &a : array){
        os << a << ", ";
    }
    return os;
}
std::ostream& operator <<(std::ostream& os, const Value value){
    os << value;
    return os;
}

Now, if I try to run it :

int main()
{
    Array a {1,2,3}; // OK
    std::cout << a;  // Segfault
}

Where's the catch ?

EDIT As pointed, there was a recursion loop.

Oreille
  • 375
  • 3
  • 11

1 Answers1

4

You have a stack overflow due to infinite recursion:

std::ostream& operator <<(std::ostream& os, const Value value){
    os << value; // call to self
    return os;
}

This would be a correct way to insert a variant into a stream:

std::visit([&](const auto& value) {
    os << value;
}, static_cast<const Value::variant&>(value));
eerorika
  • 232,697
  • 12
  • 197
  • 326