Sam
Sam

Reputation: 324

Issue with Enum usage

I have an issue with Enum (and I guess its usage): I've declared an Enum in a class and I'm trying to use it in its subclass. Here the (abstract) superclass:

//Function.h
class Function {
public:
    enum FunctionType {
        constant,
        variable,
        sum,
        mul
    };
    ...
    virtual FunctionType getType();
};

here one of its subclass:

//Const.h
#include "Function.h"

#ifndef CONST_H_
#define CONST_H_

class Const:public Function {
    ....
public:
    Const(double x);
    ....
    Function::FunctionType getType();
    ....
    ~Const();
};

#endif /* CONST_H_ */

and its implementation:

//Const.cpp
#include "Const.h"
#include "Function.h"


Function::FunctionType Const::getType(){
    return Function::FunctionType::constant;
}
....

The compiler throw the following error:

error: ‘Function::FunctionType’ is not a class or namespace
return Function::FunctionType::constant;
                 ^

I'm not able to find out why I have this error, and what's wrong with this code that sounds to me easy and sound (and of course it is not).

Upvotes: 3

Views: 499

Answers (3)

YSC
YSC

Reputation: 40070

To qualify an enum value, you don't use the enum type name:

enum enum_t { ENUM_VALUE };
auto e = ENUM_VALUE; // no enum_t::

In your case, the solution is:

struct Function {
    enum FunctionType {
        constant
    };
    virtual FunctionType getType();
};

struct Const : Function {
    Function::FunctionType getType() { return Function::constant; }
};

The fact that Function::FunctionType::constant is an error comes from enums being a C feature to declare constants. From the cppreference.com page on the enum, one can read:

Unscoped enumeration

enum name { enumerator = constexpr , enumerator = constexpr , ... } (1)
1) Declares an unscoped enumeration type whose underlying type is not fixed (in this case, the underlying type is either int or, if not all enumerator values can be represented as int, an implementation-defined larger integral type that can represent all enumerator values. If the enumerator-list is empty, the underlying type is as if the enumeration had a single enumerator with value 0).

If you want to use strongly typed, scoped enums, see @Angrew answer and enum class.

Upvotes: 9

@YSC's answer is 100% correct in explaining the error you're getting.

To add a bit broader context, the syntax you originally intended to use is supported starting from C++11 in the form of scoped enumerations. These are enumerations where implicit conversions to/from integers are not available, and the names of the enumerators are within the scope of the enumeration. They are introduced by the syntax enum class.

This is in contrast to unscoped enumerations (what you get with just using enum), where no such scoping rules exist. The enumeration name simply does not introduce scope, so using it on the left-hand side of the scope resolution operator :: is an error.

You could use a scoped enumeration in your code like this:

class Function {
public:
    enum class FunctionType {
        constant,
        variable,
        sum,
        mul
    };
    ...
    virtual FunctionType getType();
};

Function::FunctionType Const::getType(){
    return Function::FunctionType::constant;
}

Note that qualifying FunctionType::constant as Function::FunctionType::constant is not necessary within a class derived from Function; access to all members inherited from Function is implicit.

Upvotes: 4

user1723095
user1723095

Reputation: 1219

Try:

return Function::constant;

Instead of:

return Function::FunctionType::constant;

Upvotes: 0

Related Questions