is it possible to convert std::string into enum class in std::cin?

60 Views Asked by At

I'am new in cpp. Let's say we've got a class as follows:

 class Animal {
    public:
        enum class Group {mammal, bird, reptile};
    private:    
        Group group;
}

Now I'd like to initialise it in this way:

Animal::Group g;
std::cin >> g;
std::unique_ptr<Animal> dog = std::make_unique<Animal>(std::move(g));

I tried to overload istream as below and make it friend of class Animal but it doesn't work.

auto string_to_vlt(std::string const s) -> std::optional<Human::Violation>
{
    if (s == "mammal")     return Animal::Group::mammal;
    if (s == "bird")       return Animal::Group::bird;
    if (s == "reptile")    return Animal::Group::reptile;
    return std::nullopt;
}

auto operator>>(std::istream& is, Animal::Group v) -> std::istream& // friend function
{
    auto s = std::string();
    if (!(is >> s)) {
        return is;
    }
    if (auto result = string_to_vlt(s)) {
        v = *result;
    }
    return is;
}

Any ideas? Is it possible at all?

1

There are 1 best solutions below

0
Marek R On

There is cool library which address this issue Magic Enum.

It can make code work without extensive coding:

#include <iostream>
#include <memory>
#include <magic_enum.hpp>
#include <magic_enum_iostream.hpp>

using namespace magic_enum::ostream_operators; 
using namespace magic_enum::istream_operators; 

class Animal {
public:
    enum class Group {
        mammal,
        bird,
        reptile,
    };

    explicit Animal(Group g) : group { g } { 
        std::cout << "making: " << group << '\n';
    }

    ~Animal()
    {
        std::cout << "removing: " << group << '\n';
    }

private:
    Group group;
};

int main()
{
    Animal::Group g;
    while (std::cin >> g) {
        auto dog = std::make_unique<Animal>(g);
    }
    return 0;
}

https://godbolt.org/z/ae7nbvbEq

Disclaimer: Note that this library leverages some compiler specific features, so there is no warranty that it will always work. See limitations.