1

Basically, what I would like to be able to is to define operator++ for Test enum, which is a private member of a Inner class, which is private member of an Outer class. This snippet might be helpful in understanding what I want to acchieve:

class Outer{
    class Inner{
        enum Test{ONE, TWO, THREE};
    };  
};

const Outer::Inner::Test& operator++(Outer::Inner::Test& test){
    int rawTest = test;
    test = static_cast<Outer::Inner::Test>(++rawTest);
    return test;
}

Unfortunately above will not compile with error, that Test is private member, so next I tried following:

#include <iostream>
using namespace std;
class Outer{
    class Inner{
        enum Test{ONE, TWO, THREE}; 

        friend const Test& operator++(Test& test);
    };  

    friend const Inner::Test& operator++(Inner::Test& test);
};

const Outer::Inner::Test& operator++(Outer::Inner::Test& test){
    int rawTest = test;
    test = static_cast<Outer::Inner::Test>(++rawTest);
    return test;
}

this still does not work, because Test is defined in private Inner class, so I would have to friend both classes together, although there is no point in it (I do not want to access Test enum in Outer class. Just to be able to use operator++ in inner class)

Of course I can make function inline like this:

#include <iostream>
using namespace std;
class Outer{
    class Inner{
        enum Test{ONE, TWO, THREE}; 

        friend const Test& operator++(Test& test){
            int rawTest = test;
            test = static_cast<Outer::Inner::Test>(++rawTest);
            return test;
        }
    };  

};

, but I might not want this, because of let's say some magical additional logic, which I want to have in .cpp file. How should I declare operator++ properly to be able to operator on Test enum?

EDIT: This is surely not a duplicate of given question, as I want to simply declare operator++ for given enum in nested class. The provided duplicate question is about accessing member of Inner class from an Outer class function.

EDIT: Bringing here Holt's comment: "Actually, clang accepts your second code (with the two friend declaration), which would be the standard way. Whether this is a clang extension or a g++ bug I don't know... Maybe you should reformulate your question to get the attention of some language-lawyer around there ;)" Maybe the more appropriate question would be, whether it is right, that gcc and msvc (which I tried) does not allow double fiendship code, or not, as in my opinion C++ standard should somehow allow clean coding in such cases like this one (in fact not so complicated case).

DawidPi
  • 2,285
  • 2
  • 19
  • 41
  • Since `Test` is a private member of `Inner`, and `Inner` is a private member of `Outer`, I don't see how anything could possibly use this enum, much less increment it. Your question is unclear. – Sam Varshavchik Oct 10 '16 at 11:00
  • This is not a duplicate. I made some clarifications. Just read it out once again. – DawidPi Oct 10 '16 at 11:15
  • @SamVarshavchik This is snippet. Anything from Inner class may want to increment the value of type Test (hello there can be other methods and it's implementation can use ++ on variable of Type Test). it's quite obvious... – DawidPi Oct 10 '16 at 11:21
  • @Pixelchemist Of course not. Just read it once again. I want to simply define operator++ for enum. I may use it just in the Inner class, but still I want it. – DawidPi Oct 10 '16 at 11:22
  • @StoryTeller I return reference to the variable, which I take into function as reference to the argument. See it closer. (return test, where test is taken by reference). This won't cause any problems! – DawidPi Oct 10 '16 at 11:56
  • 1
    @DawidPi, the overhead of using a reference to an enum is way more than just passing it by value. Even if the code is correct. – StoryTeller - Unslander Monica Oct 10 '16 at 11:57
  • @StoryTeller Sure. I have to agree with this. – DawidPi Oct 10 '16 at 12:53
  • 1
    @DawidPi, never mind. I had my coffee. You have to pass it by reference for operator++ to work as expected (do'h). – StoryTeller - Unslander Monica Oct 10 '16 at 12:55
  • @StoryTeller good to know :) I haven't thought of this also. Just did this as for any ++operator :) – DawidPi Oct 10 '16 at 13:09
  • 1
    @DawidPi Actually, clang accepts your second code (with the two `friend` declaration), which would be the standard way. Whether this is a clang extension or a g++ bug I don't know... Maybe you should reformulate your question to get the attention of some language-lawyer around there ;) – Holt Oct 10 '16 at 13:30
  • @Holt good idea. Thanks a lot! I tried those on gcc and msvc both failed :) – DawidPi Oct 10 '16 at 13:46

1 Answers1

2

What you want to declare is a "global" function (operator++) that will only be used inside Outer::Inner due to the access on Test. I don't know if this is possible, but a simple work around would be to fallback to a static method of Inner:

#include <iostream>

class Outer{
    class Inner{
        enum Test{ONE, TWO, THREE}; 

        static Test& pre_inc(Test&);
        friend Test& operator++(Test& test) {
            return pre_inc(test);
        }
    };  
};

auto Outer::Inner::pre_inc(Test& test) -> Test& {
    int rawTest = test;
    test = static_cast<Test>(++rawTest);
    return test;
}
Holt
  • 36,600
  • 7
  • 92
  • 139