Tom de Geus
Tom de Geus

Reputation: 5965

Using class as enum-like, or with a specific value

I would like my function to accept a compression-level (which can take values 0..9). I want the user to be able to set the level manually Compression(7) or use some defaults like Compression::High, Compression::Medium.

I thought of the following:

class Compression {
public:
    Compression(size_t level) : m_level(level) {};
    static const Compression Medium;
    static const Compression High;
    size_t get() const { return m_level; };
private:
    size_t m_level;
};

const Compression Compression::High{9};
const Compression Compression::Medium{5};

The problem is that I am developing a header-only library, and doing this leads to "multiple definitions of 'Compression::High' and 'Compression::Medium". How can this be solved?


Edit

Challenges:

Upvotes: 3

Views: 113

Answers (2)

463035818_is_not_an_ai
463035818_is_not_an_ai

Reputation: 122133

Not the nicest, but as a last resort you could use static functions that return the desired instance:

class Compression {
public:
    Compression(size_t level) : m_level(level) {};
    static Compression Medium() { return 3; }
    static Compression High() { return 5;}

    size_t get() const { return m_level; };
private:
    size_t m_level;
};

Using it would require additional ():

foo( Compression::High() );

PS: If you want to distinguish between size_t and Compression I would suggest to make the constructor explicit to avoid potential confusion. One thing that can go wrong is that you forgot to provide a bar(size_t) overload and this:

size_t x = 3;
bar(x);

will unexpectedly and silently call the bar(Compression) overload.

Upvotes: 1

Tomasz Tarkowski
Tomasz Tarkowski

Reputation: 123

GCC version 9.3.0 accepts that code (C++17):

inline const Compression Compression::High{9};
inline const Compression Compression::Medium{5};

Please note the inline word.

Upvotes: 4

Related Questions