Enum class "put to" operator overloading

Hi all,

Is the class Color defined below a scoped enum class? Is it due to the word class in its definition?


1
2
3
4
5
6
7
8
9
10
int main()
{
	enum class Color { red, blue, green };
	Color y{ 6 }; 

	cout << "y  = " << y << endl;
	
	system("pause");
	return 0;
}


The second question is, when the value y is to be printed, VS 2019 shows an error of no matching << operator for y.
How to overload the "put to" operator for such a value, please?

Last edited on
> Is the class Color defined below a scoped enum class? Is it due to the word class in its definition?

Yes.

> How to overload the "put to" operator for such a value, please?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <iostream>

enum class colour { RED, GREEN, BLUE };

std::ostream& operator<< ( std::ostream& stm, colour clr )
{
    switch(clr)
    {
        case colour::RED : return stm << "RED" ;
        case colour::GREEN : return stm << "GREEN" ;
        case colour::BLUE : return stm << "BLUE" ;
        default: return stm << "colour{" << int(clr) << '}' ;
    }
}

int main()
{
    const colour clr_sky = colour::BLUE ;
    std::cout << clr_sky << '\n' ; // BLUE

    const colour x { 6 } ;
    std::cout << x << '\n' ; // colour{6}
}

http://coliru.stacked-crooked.com/a/0e71fdb4c1f74e46
Thank you. What does "scoped" mean here, please?
I think it's seemingly not scoped because we can set values beyond its list to an object of that type!
> I think it's seemingly not scoped because we can set values beyond its list to an object of that type!

C++17 relaxed that restriction for scoped enums
(and also for unscoped enums which have a fixed underlying type).

Both scoped enumeration types and unscoped enumeration types whose underlying type is fixed can be initialized from an integer without a cast, using list initialization, if all of the following is true:

. the initialization is direct-list-initialization
. the initializer list has only a single element
. the enumeration is either scoped or unscoped with underlying type fixed
. the conversion is non-narrowing

This makes it possible to introduce new integer types (e.g. SafeInt) that enjoy the same existing calling conventions as their underlying integer types, even on ABIs that penalize passing/returning structures by value.
https://en.cppreference.com/w/cpp/language/enum


Note:

For a scoped enumeration type, the underlying type is int if it is not explicitly specified.
http://eel.is/c++draft/dcl.enum#5

For an enumeration whose underlying type is fixed, the values of the enumeration are the values of the underlying type. http://eel.is/c++draft/dcl.enum#8
Thank you for your explanations.
The subject is rather twisted. Also, personally I've found https://en.cppreference.com almost never easy to understand. I believe they're not but for experts!

Anyway, still there's a little ambiguity in the word scoped. I suggest that we attempt to clarify it by this question.

This is a scoped (since there's the word class in the definition) enumeration list called colour_1: enum class colour_1 { RED, GREEN, BLUE };.

And this is an unscoped (since there's not the word class in the definition) enumeration list called colour_2: enum colour_2 { RED, GREEN, BLUE };.

What are the differences between these two, please?
Last edited on
> What are the differences between these two, please?

They are summarised here: http://www.stroustrup.com/C++11FAQ.html#enum
Topic archived. No new replies allowed.