Как я могу написать enum класс в файл и получить к нему доступ в C ++? - PullRequest
0 голосов
/ 12 июня 2018

Я пытаюсь записать содержимое объекта класса в файл.У объекта есть член класса enum, и я не могу записать его в файл с использованием ofstream.

Я получаю следующую ошибку.

error: no match for ‘operator<<’ (operand types are ‘std::basic_ostream<char>’ and ‘EnumClass_scope::EnumCass_name’)

Любые выводы будут полезны.

Ответы [ 3 ]

0 голосов
/ 12 июня 2018

Один из способов - привести тип enum к типу подложки.Это можно сделать с помощью уже определенного std::underlying_type_t, чтобы получить внутреннее представление перечисления.

    template < typename T>
auto toUnderlayingType( T t )
{
    return static_cast<std::underlying_type_t< T >>( t );
}

    template < typename T, typename U = std::underlying_type_t< T > >
void readToEnum( U u , T& t )
{
    t = static_cast< T >( u );
}

class Y
{
    public:

        enum class X
        {
            ONE,
            TWO
        } x;

        Y(): x{X::ONE} { }

        void Print()
        {
            std::cout << toUnderlayingType(x) << std::endl;
        }

        void Read()
        {
            std::underlying_type_t< X > tmp;
            std::cin >> tmp;
            readToEnum( x, tmp );
        }
};



int main()
{
    Y y;
    y.Print();
}

Но в случае сериализации даже лучше использовать лучшее представление содержимого и данных.Поскольку отражение все еще не является частью c ++, вам нужно преобразовать значение enum в любой полезный вывод и обратно.Возможно, вы напишите в файл текст «ОДИН» вместо 0.Но все это для широкого ответа.Существует длинный список библиотек сериализаторов, таких как boost и cerial

. Необходимо проверить, является ли входящее значение действительным.Имея приведенный выше пример и присвоив ему числовое значение 3, значение enum является недействительным.Эта тема уже обсуждалась здесь: Что произойдет, если вы укажете недопустимое значение static_cast в enum class?

0 голосов
/ 12 июня 2018

Другой вариант - вручную перегрузить оператор << для вашего перечисления:

#include <iostream>

enum class ESomething
{
    Nothing,
    Something,
    Everything,
};

std::ostream& operator<<(std::ostream& os, const ESomething& other)
{
    switch (other)
    {
    case ESomething::Nothing:
        os << "Nothing";
        break;
    case ESomething::Something:
        os << "Something";
        break;
    case ESomething::Everything:
        os << "Everything";
        break;
    default:
        break;        
    }
    return os;
    // Alternatively: std::cout << std::underlying_type(other); return os;
}

int main()
{
    ESomething hello = ESomething::Something;
    std::cout << hello << '\n';

    return 0;
}

Где вы можете точно решить, что выводить в каждом отдельном случае, или просто привести его к базовому типу какдругие ответы упоминали и выводили это.Выбор за вами.

0 голосов
/ 12 июня 2018

Преобразовать переменную в целое число перед записью.Используйте целочисленную временную переменную при чтении.

std::fstream stream;
enum class Enum { ... };

Enum variable;
stream << static_cast<int>(variable);

int temporary;
stream >> temporary;
variable = static_cast<Enum>(temporary);

Если вы определили enum с типом, отличным от int, используйте этот тип.Например, с enum class Enum : unsigned long long используйте static_cast<unsigned long long>.

...