Operator ++ for embedded private enum - 哪个编译器是对的?

时间:2016-10-10 10:56:56

标签: c++ enums friend-function

基本上,我希望能够为Test枚举定义operator ++,它是Inner类的私有成员,它是Outer类的私有成员。这段代码可能有助于理解我想要实现的目标:

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;
}

不幸的是上面不会编译错误,Test是私有成员,所以接下来我尝试了以下:

#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;
}

这仍然不起作用,因为Test是在私有的内部类中定义的,所以我必须将两个类放在一起,尽管它没有意义(我不想在外类中访问Test枚举。只是为了能够在内部类中使用operator ++)

当然我可以像这样内联函数:

#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;
        }
    };  

};

,但我可能不想要这个,因为让我们说一些神奇的附加逻辑,我想在.cpp文件中。我应该如何正确地声明operator ++以便能够在Test enum上运算?

编辑: 这肯定不是给定问题的重复,因为我想简单地在嵌套类中为给定的枚举声明operator ++。提供的重复问题是关于从外部类函数访问Inner类的成员。

编辑: 带来霍尔特的评论: “实际上,clang接受你的第二个代码(带有两个朋友的声明),这将是标准的方式。无论是铿锵声扩展还是g ++错误我都不知道......也许你应该重新设计你的问题以获得一些语言律师的注意力在那里;)“也许更合适的问题是,是否是正确的,gcc和msvc(我试过)不允许双重恶魔代码,或者不是,因为在我看来C ++标准应该在某些情况下允许清洁编码,例如这种情况(事实上并非如此复杂)。

1 个答案:

答案 0 :(得分:2)

您想宣布的是全球&#34;函数(operator++),由于Outer::Inner上的访问权限,只会在Test内使用。我不知道这是否可行,但一个简单的解决办法是回归到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;
}