Jon
Jon

Reputation: 1705

Trying to combine flags within enum value

Trying to construct a simple enum to contain a set of ios:: flags for easier reference, parameter passing, etc. I want to be able to make a call:

resultCode = DoSomething(param, TRUNCATE);

ResultCode DoSomething(int param, FileOperation_t operation) {...}

I have defined my enum thusly:

typedef enum {
    TRUNCATE = std::ios::out | std::ios::trunc,
    APPEND   = std::ios::out | std::ios::app
} FileOperation_t;

Compiling this results in:

error: calls to overloaded operators cannot appear in a constant-expression
     TRUNCATE = std::ios::out | std::ios::trunc,
                                          ^

I do not understand what this error means. What am I doing wrong here and how do I accomplish what I am trying to do?

gcc (GCC) 4.8.5 20150623 (Red Hat 4.8.5-28)

Upvotes: 3

Views: 322

Answers (1)

HolyBlackCat
HolyBlackCat

Reputation: 96286

Your compiler seems to use -std=c++98 by default. Use -std=c++11 flag instead and the code will compile.

In C++98 function calls (including overloaded opeator calls) weren't allowed in compile-time constant expressions (since there were no constexpr semantics).


Though, it's not required to compile according to the standard, even with the flag:

This page says std::ios::openmode is a typedef for an implementation-define type, satisfying BitmaskType concept.

While BitmaskType has to have operator overloads for &, | and so on, there is no guarantee that these operators are constexpr, nor that the type itself is convertible to an integral type.

For maximum compatibility, use plain const variables instead:

const std::ios::openmode TRUNCATE = std::ios::out | std::ios::trunc;
const std::ios::openmode APPEND   = std::ios::out | std::ios::app;

(This solution will also work with C++98, if you can't use newer standards.)

Upvotes: 3

Related Questions