Thread: Incrementing enum types

  1. #1
    JarretteBeast
    Guest

    Incrementing enum types

    check out this program

    #include <iostream.h>
    #include <iomanip.h>

    typedef char* STRING;
    typedef char NAME [41];
    typedef double AMOUNT;
    enum DAY {mon, tue, wed, thu, fri, sat, sun};

    int main()
    {
    STRING day_names [7] = {"Monday", "Tuesday", "Wednesday"
    , "Thursday", "Friday", "Saturday", "Sunday"};
    AMOUNT sales [7];
    NAME salesperson;
    AMOUNT max_sales,
    total_sales;
    DAY day,
    max_day;

    cout << setprecision (2)
    << setiosflags (ios::fixed)
    << setiosflags (ios::showpoint);

    cout << "\nEnter the name of the salesperson: ";
    cin.getline (salesperson, 41);

    for (day = mon; day <= sun; ++int(day))
    {
    cout << "\n\nEnter the sales for " << day_names[day] << ": ";
    cin >> sales [day];
    }

    total_sales = 0;
    max_day = mon;
    max_sales = sales[mon];

    for (day = mon; day <= sun; ++int(day))
    {
    if (sales[day] > max_sales)
    {
    max_sales = sales[day];
    max_day = day;
    }
    total_sales += sales[day];
    }

    cout << "\n\nThe total sales for " << salesperson
    << " is " << total_sales << ".";
    cout << "\n\nThe highest sales was " << max_sales << ".";

    cout << "\n\nThe highest sales occurred on "
    << day_names[max_day] << ".";

    return 0;
    }


    I get two errors telling me that I can't increment the day variable even tho i declared it as an int in the for loop. Is this compiler specific? I'm using microsoft visual C++

  2. #2
    Registered User
    Join Date
    Mar 2002
    Posts
    1,595
    You could try this:

    ++day;

    but since enum are user defined types, the ++ operator may not be defined for enums, eventhough an enum is an int by another name. Won't hurt to try if you haven't already

    If that doesn't work you could try casting to an int and then incrementing:

    ((int)day)++;

    but that might not work since you are probably incrementing the int and not the enum it was casted from. Again easy enough to try.

    If those don't work, then I would probably use an int as though it were an enum. As indicated above enums are ints by aother name. You can use ints to represent enums, as long as the int is a valid enum value. enum values start at zero by default and increment by one for each additional enum. Obviously you can override the default settings if you want to. Therefore I would try something like this:

    int i;
    for (i = 0; i < 7; ++i)
    {
    cout << "\n\nEnter the sales for " << day_names[i] << ": ";
    cin >> sales [i];

  3. #3
    Cheesy Poofs! PJYelton's Avatar
    Join Date
    Sep 2002
    Location
    Boulder
    Posts
    1,728
    Yeah, the books I have say that you can't use arithmetic with enums, although I wouldn't doubt if some compilers out there let you do it. You'll have to cast it. I'm not sure if what elad wrote would work:

    ((int)day)++;

    But this should work on any compiler:

    day=int(day)+1;

  4. #4
    Registered User
    Join Date
    Apr 2003
    Posts
    27

    ...

    still get:

    error C2440: '=' : cannot convert from 'int' to 'enum DAY'
    Conversion to enumeration type requires an explicit cast (static_cast, C-style cast or function-style cast)

    cout << "\aBIOTCH";

  5. #5
    C++ Developer XSquared's Avatar
    Join Date
    Jun 2002
    Location
    Ontario, Canada
    Posts
    2,718
    day=DAY(int(day)+1);
    Naturally I didn't feel inspired enough to read all the links for you, since I already slaved away for long hours under a blistering sun pressing the search button after typing four whole words! - Quzah

    You. Fetch me my copy of the Wall Street Journal. You two, fight to the death - Stewie

  6. #6
    Registered User
    Join Date
    Apr 2003
    Posts
    27

    hrmmm?

    /applause

    x gets the prize!

    now why the hell did that work?

    cout << "\aBIOTCH";

  7. #7
    Registered User
    Join Date
    Nov 2002
    Posts
    1,109
    because you are casting it as an int to increment it, then you have to cast that int as a DAY to get the desired result.

    i.e. enum types have int equivalents

    so say you have day as mon. mon = 0. so you cast it as the int equivalent, which is zero, add 1, then cast that int (which is 1) as a DAY; hence you end up with tues.

    edit: this should be done because day is of type DAY

  8. #8
    Registered User
    Join Date
    Apr 2003
    Posts
    27
    wow, that even makes sense!

    Hey I'm really happy to have found this board, I'm an IS major who's taking C++ atm. I really love the language, I guess because last semester I took COBOL.

    Anyway, thanks for all the replies and help!
    cout << "\aBIOTCH";

  9. #9
    Registered User
    Join Date
    Apr 2003
    Posts
    27
    wow, that even makes sense!

    Hey I'm really happy to have found this board, I'm an IS major who's taking C++ atm. I really love the language, I guess because last semester I took COBOL.

    Anyway, thanks for all the replies and help!
    cout << "\aBIOTCH";

  10. #10
    Registered User
    Join Date
    Feb 2003
    Posts
    596
    You can do arithmetic just as you wanted with C enum types, but this is not supported in the C++ standard.

    However, it turns out that your program works fine in Dev-C++ ver.4 and Borland C++ Builder 5.5. I guess those two compilers are "non-standard" in this respect. In unixland, the CC and g++ compilers both gave errors like the one you got from MSVC.

    So you have to go through contortions like xsquared's solution to use the enum the way you wanted.

    But why use enum at all in your program? You're not using it to restrict user input, because in your app the user is never asked to input the day. So why not just:
    Code:
    ...
    int day;
    ...
    for (day = 0; day <=6; ++day)
    ...
    Granted, your original way did add a little to the program's readability, but I think the meaning of a variable named "day" with values from 0-6 is pretty obvious anyway. And if you have to do this
    Code:
    day=DAY(int(day)+1);
    to count through the days, I think that negates any readability benefit, and that the simpler approach, just using ints, is more readable.

  11. #11
    Registered User
    Join Date
    Apr 2003
    Posts
    27
    oh im just going through lessons and examples in my textbook. Right now im trying to learn structures and enums. So yeah it was prolly redundant to use enum in that, but it's helping me learn enums.
    cout << "\aBIOTCH";

  12. #12
    Registered User
    Join Date
    Jan 2003
    Posts
    648
    Use code tags!

  13. #13
    Programming Sex-God Polymorphic OOP's Avatar
    Join Date
    Nov 2002
    Posts
    1,078
    You can always just overload operators for your enumerated types.

    What I usually do to make working with multiple different enum types quick and easy, as well as to avoid name conflicts, is I don't ever use the c++ enum type anymore, but instead use standardized integral types of defined length and format. This, firstly, makes your code much more easily to be portable. Next, I made a templated Enumeration class with 1 template parameter for the [usually] integral type to be used. The class completely consists of inline protected members and overloaded operators, and is simply used as a base from which to derive your "enums."

    Then, anytime you want a new type of enumeration, you create a new class for it, use private inheritance on the Enumeration type with the integral template parameter to optimize how much space you need for the type (IE an 8-bit unsigned int if the enumeration only needs a small range of possible values, or even an unsigned 64 bit integer if you are using a very large set of bitflags). Inside the class definition you define public static constants of the template type, which you use to act as your enum constants. Finally, you promote any member functions from the base to be public in the child, picking and choosing which functions to promote depending on whether or not it makes sense to, for instance, incremement an instance.

    You still get typesafety, although now on an object level. Also, since the enumerations are all privately derived from the Enum type, you can't convert to the base, which is good, because they should be thought of as completely different types.

    So now, whenever you need an enumeration of a certain type, you use the object type. You specify it's value by doing ObjectType::ConstantName. You only use the constant names as temporary objects for construction. You should never explicitly declare an object of the interal type.

    The only downside is that it's, of course, possible to construct the object with a different constant if the integral type is the same or if there is a built-in conversion between the types. This only happens during construction because everywhere else, you use the object's type, not the integral type. Also, if you consider other solutions, such as opengl's "super enum," they lack any form of typesafety on enumerations because they use exactly the same type for all of them (of course, since opengl is procedural there wasn't much of a choice)!

    Since the constants are public, static and nested in the class definitions, you never have to worry about name conflicts, but you can still access them externally. If you have ever worked with a lot of enumerations, you know what I'm talking about. For instance, it makes sence to have a None constant for many different enumerations which would normally result in conflicts. Since, with my implementation, the constants are encapsulated in their appropriate type definitions, name conflicts are never a problem, so you can have many types with enumerations of the same name, without ever having problems.

    Since the integral type is a template parameter, not only do you benefit from control of the size, etc. but it also makes it very simple to work with fileio. When using enum, you have no control of the size of the datatype (unless you use bitfields, though even then, you may have format problems and you have no way of creating a constant of larger size than your compiler's enum). With my implementation, you get low-level control with high-level benefits, and because all of the member functions are inlined, speed should not be an issue.

  14. #14
    Skunkmeister Stoned_Coder's Avatar
    Join Date
    Aug 2001
    Posts
    2,572
    the correctest solution in c++ as has already been noted and as i would have told you about 8 hrs ago if not for that poxy error that plagues this board is to overload the ++ operator. You should view xsquared solution as a legal hack. In fact you would use a very similar hack inside of operator ++ but you would also get the benefit of not falling off the end of your enum.
    Free the weed!! Class B to class C is not good enough!!
    And the FAQ is here :- http://faq.cprogramming.com/cgi-bin/smartfaq.cgi

  15. #15
    Banned
    Join Date
    Jan 2003
    Posts
    1,708
    what about just making it an int.

    int DAY = MONDAY;
    DAY++;

    that should work for ye

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. invalid types 'int[int]' for array subscript
    By kolistivra in forum C++ Programming
    Replies: 6
    Last Post: 12-11-2010, 12:57 PM
  2. Replies: 6
    Last Post: 08-23-2008, 01:16 PM
  3. The Interactive Animation - my first released C program
    By ulillillia in forum A Brief History of Cprogramming.com
    Replies: 48
    Last Post: 05-10-2007, 02:25 AM
  4. Dikumud
    By maxorator in forum C++ Programming
    Replies: 1
    Last Post: 10-01-2005, 06:39 AM
  5. enum types
    By Unregistered in forum C++ Programming
    Replies: 13
    Last Post: 08-31-2002, 08:14 AM