-2

As mentioned in this question's title, is there a syntax to do this?

class Food : public Edible {
public:
    class Fruit : public FruitBase { //note: Fruit must be a class and a subclass of Food.
    public:    
        enum Type {                  //note: Type must be inside Fruit and must be a plain enum.(not enum class)
            APPLE,
            GRAPES,
            ORANGE,
        };
        //...
    };
    enum { CAKE, CHOCOLATE };
    //...
};

void func(){
    Food snack;
    //...
    auto typeA = snack.Fruit::APPLE;    //<---this is syntax error.
    auto typeG = snack.GRAPES;          //<---also syntax error. 
    auto typeO = Food::Fruit::ORANGE;   //<---this is OK, but not my target.

    auto typeC = snack.CAKE;           //<---this is OK.

    //...


}

I prefer the syntax of typeG. My 2nd preference is typeA. I'm currently using typeO in my code but I need to access those enum constants from object snack instead of class Food. Since typeC is possible, I hope there's also a way to do this on enums inside a subclass.

acegs
  • 2,621
  • 1
  • 22
  • 31
  • What problem will doing so solve? –  Jul 09 '18 at 02:13
  • https://stackoverflow.com/questions/18335861/why-is-enum-class-preferred-over-plain-enum – James Poag Jul 09 '18 at 02:15
  • @JamesPoag thanks for the link. But in the part of our project where my question originated, we decided to choose the plain enum. We researched it and weighted the advantages and disadvantages. But there are part in our project where we use `enum class`. We are adviced not to just follow the `best practices` info from the internet and confirm it ourselves which is better to use at specific kind of situation/problem. – acegs Jul 09 '18 at 02:36
  • @Nicky, apology for not exposing further details on my code. it's part of a company project. The problem is this: The `Fruit` subclass name exists on several `Food` classes(with different class names) that are not connected to each others. so `Fruit` subclass is a convention for a data-structure we are using. The `Fruit::Type` is used as parameter passed in functions. Each time we passed `Fruit::Type` object, currently, we also specify `Food` so it's `void testFunc(Food1::Fruit::APPLE)`. But there are several `Food*` classes. It's actually about maintainability of code. – acegs Jul 09 '18 at 02:49
  • I guess the answer to my question for now is a `No, there's no syntax support yet`. But I guess the `auto typeA = snack.Fruit::APPLE;` syntax is good to be supported in c++. – acegs Jul 10 '18 at 02:56

2 Answers2

1

Something like this :

class Food {
public:
    class Fruit {      
    public:                       
        enum  Type {                                
            APPLE,
            GRAPES,
            ORANGE,
        };
        Type type;
    };
    Fruit fruit;

    enum class Foodies{ CAKE, CHOCOLATE };
    Foodies foodies;
};

void func() {
    typedef Food::Fruit::Type FruitType;

    Food snack; 
    auto typeA = snack.fruit.type = FruitType::APPLE;
}
seccpur
  • 4,996
  • 2
  • 13
  • 21
1

UPDATE

You can create an instance of Fruit inside Food, this way you can access the members of Fruit inside Food. like this:

class Food : public Edible 
{
public:
    class Fruit : public FruitBase 
    { 
    public:
        enum Type{ APPLE, GRAPES, ORANGE };
    };
    static Fruit fruit; // -> this is what I was talking about

    enum { CAKE, CHOCOLATE };
};


int main()
{
    Food food;
    auto apple = food.fruit.APPLE; // this is not so different of your 'typeG'
}

Now about Fruit need to be subclass of Food but Fruit is already subclass of FruitBase, so multiple inheritance is another question maybe this helps you.

OLD

Why not use only inheritance like this:

#include <iostream>

class Fruit 
{
public:
    enum Type { APPLE, GRAPES, ORANGE };
};

class Food : public Fruit
{
public:
    enum Foods { CAKE, CHOCOLATE };
};

int main()
{

    Food food;
    auto apple =  food.Type::APPLE;
}

If you really prefer typeG as you said you can make enum Type scope of the class Fruit like this:

#include <iostream>

class Fruit 
{
public:
    enum { APPLE, GRAPES, ORANGE };
};

class Food : public Fruit
{
public:
    enum Foods { CAKE, CHOCOLATE };
};

int main()
{

    Food food;
    auto apple = food.APPLE;
}
Muzol
  • 301
  • 1
  • 11
  • I forgot to mention that `Food` is a derived class of some `FoodBase` class. And `Fruit` MUST be a subclass of `Food`. I'll edit my question. Thanks for the answer! – acegs Jul 09 '18 at 03:01
  • I prefer not adding additional bytes(`Fruit`) on `Food` class just to add a way to access those enums. `Fruit` in our case contains many bytes. I tested your code and it can be achieved by adding `static const` to the `Fruit` instance. To avoid creating an instance of `Fruit` (even if its a static const object) I tried `static const Fruit::Type fruit;` but that would need the enums to be inside class/struct to work. `struct Type { enum { APPLE, GRAPES, ORANGE }; };` – acegs Jul 10 '18 at 02:47
  • sorry I forgot to put `static` before Fruit. the best way to you use nested classes is `auto typeO = Food::Fruit::ORANGE;` without instantiate the nested class. [look this](https://en.cppreference.com/w/cpp/language/nested_types) – Muzol Jul 10 '18 at 04:31