简体   繁体   English

如何将枚举类写入文件并在C ++中访问它?

[英]How can I write an enum class to a file and access it in C++?

I am trying to write the contents of a class object into a file. 我正在尝试将类对象的内容写入文件。 The object has an enum class member and I am unable to write it into a file using ofstream. 该对象具有一个枚举类成员,并且我无法使用ofstream将其写入文件。

I get the following error. 我收到以下错误。

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

Any leads would be helpful. 任何线索都将有所帮助。

One way is to cast the enum type to the underlaying type. 一种方法是将枚举类型转换为基础类型。 This can be done with already defined std::underlying_type_t to get the internal representation of the 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();
}

But in the case of serialization it is even better to use a better representation of content and data. 但是在序列化的情况下,最好使用更好的内容和数据表示形式。 As reflection is still not part of c++ you have to convert the enum value to any useful output and back. 由于反射仍然不是c ++的一部分,因此您必须将枚举值转换为任何有用的输出,然后再转换回去。 Maybe you will write text like "ONE" instead of 0 to the file. 也许您会在文件中写入“ ONE”之类的文字而不是0。 But all this is to broad for this answer. 但这一切对于这个答案都是广泛的。 There are a long list of serializer libraries like boost and cerial 串行器库很长,例如boostcerial

And you have to check if the incoming value is a valid one. 并且您必须检查输入值是否为有效值。 Having the example above and assign a numerical 3 to it, the enum value is invalid. 有了上面的示例并为其分配了数字3,则枚举值无效。 That topic is already discussed here: What happens if you static_cast invalid value to enum class? 该主题已在此处讨论: 如果static_cast无效值枚举类,会发生什么?

Another option would be to manually overload the << operator for your enum: 另一种选择是为您的枚举手动重载<<操作符:

#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;
}

Where you could decide exactly what to output on each separate case, or simply cast it to the underlying type as other answers have mentioned and output that. 您可以在哪里确定在每个单独的案例中要输出什么,或者将其转换为其他答案提到的基础类型并将其输出。 The choice is yours. 这是你的选择。

Convert variable to integer before writing. 在写入之前将变量转换为整数。 Use integer temporary variable when reading. 读取时使用整数临时变量。

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

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

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

If you defined enum with other type than int , use that type. 如果您使用除int之外的其他类型定义了枚举,请使用该类型。 For example, with enum class Enum : unsigned long long , use static_cast<unsigned long long> . 例如,对于enum class Enum : unsigned long long ,请使用static_cast<unsigned long long>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM