Eric David Sartor
Eric David Sartor

Reputation: 597

Using enumerated class values to call an array element in C++

My code:

Enumerations.h

#ifndef ENUMERATIONS_H
#define ENUMERATIONS_H

enum class Employees
{
    ERIC,
    RYAN,
    EMILY
};

#endif

Structs.h

struct Employee
{
    std::string name;
    double wage;
};

Review.cpp

#include "stdafx.h"
#include <iostream>
#include <string>
#include "Enumerations.h"
#include "Structs.h"

Employee employeeArray[3];

    employeeArray[0] = { "Eric Sartor", 18.75 };
    employeeArray[1] = { "Ryan Ulch", 20.36 };
    employeeArray[2] = { "Emily Gover", 18.75 };

cout << employeeArray[Employees::RYAN].name;

So I'm trying to do something that I read in my C++ tutorial, where you call an array element (a struct) via an enumerated value. Earlier in the tutorial, it's recommended that if you compiler is C++11 compliant (which mine is) that is it better to use an enumerated class rather than a regular enumeration.

I'm noticing that when trying to call my element from my array via the Employees::RYAN enumerated value, it gives me an error that says "expression must have integral or unscoped enum type". If I remove the class keyword from my enumeration so it's just enum Employees and I change the array index to RYAN, it works fine. Am I missing something, or does this just not work with an enumerated class?

Hopefully I was clear enough. In the example on the tutorial, he actually DID NOT use an enumerated class, just a regular enumeration, even though he explicitly said earlier to always do that if you can...hopefully someone can clarify this for me!

Upvotes: 5

Views: 1441

Answers (2)

Vlad from Moscow
Vlad from Moscow

Reputation: 310990

From the C++ Standard (5.2.1 Subscripting)

1 A postfix expression followed by an expression in square brackets is a postfix expression. One of the expressions shall have the type “array of T” or “pointer to T” and the other shall have unscoped enumeration or integral type....

There is no implicit conversion from a scoped enumeration to an integral type.

If you want to use a scoped enumeration as an index you have explicitly cast it to some integral type. For example

cout << employeeArray[static_cast<int>( Employees::RYAN )].name;

Upvotes: 0

David G
David G

Reputation: 96810

An enumeration with an enum-key of class or struct is a scoped enumeration. Scoped enumerations don't have an implicit conversion to int.

The value of an enumerator or an object of an unscoped enumeration type is converted to an integer by integral promotion (4.5). [ Example:

enum color { red, yellow, green=20, blue };
color col = red;
color* cp = &col;
if (*cp == blue) // ...

makes color a type describing various colors, and then declares col as an object of that type, and cp as a pointer to an object of that type. The possible values of an object of type color are red, yellow, green, blue; these values can be converted to the integral values 0, 1, 20, and 21. Since enumerations are distinct types, objects of type color can be assigned only values of type color.

color c = 1; // error: type mismatch,
// no conversion from int to color
int i = yellow; // OK: yellow converted to integral value 1
// integral promotion

Note that this implicit enum to int conversion is not provided for a scoped enumeration:

enum class Col { red, yellow, green };
int x = Col::red; // error: no Col to int conversion
Col y = Col::red;
if (y) { } // error: no Col to bool conversion

— end example ]

You can explicitly cast the enumerator to int instead:

cout << employeeArray[static_cast<int>(Employees::RYAN)].name;

Upvotes: 7

Related Questions