【问题标题】:Operator++ for nested private enum - which compiler is right?嵌套私有枚举的运算符++ - 哪个编译器是正确的?
【发布时间】:2016-10-10 10:56:56
【问题描述】:

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

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 是在私有 Inner 类中定义的,所以我必须将这两个类一起加为好友,尽管这没有意义(我不想在 Outer 类中访问 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 枚举进行操作?

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

编辑: 把霍尔特的评论带到这里: “实际上,clang 接受你的第二个代码(带有两个朋友声明),这将是标准方式。无论这是一个 clang 扩展还是一个我不知道的 g++ 错误......也许你应该重新表述你的问题以获得周围的一些语言律师的注意;)”也许更合适的问题是,无论是否正确,gcc 和 msvc(我尝试过)是否不允许双重权限代码,正如我认为 C++ 标准应该以某种方式允许在这种情况下进行干净的编码(实际上不是那么复杂的情况)。

【问题讨论】:

  • 由于TestInner 的私有成员,而InnerOuter 的私有成员,我看不出有什么东西可以使用这个枚举,更不用说增量了它。您的问题不清楚。
  • 这不是重复的。我做了一些澄清。再读一遍。
  • @DawidPi,使用枚举引用的开销不仅仅是通过值传递它。即使代码是正确的。
  • @DawidPi,没关系。我喝了咖啡。您必须通过引用传递它,operator++ 才能按预期工作(do'h)。
  • @DawidPi 实际上,clang 接受您的第二个代码(带有两个 friend 声明),这将是标准方式。这是一个clang扩展还是一个我不知道的g ++错误......也许你应该重新提出你的问题以引起那里一些语言律师的注意;)

标签: c++ enums friend-function


【解决方案1】:

您要声明的是一个“全局”函数 (operator++),由于对 Test 的访问,该函数只能在 Outer::Inner 内部使用。我不知道这是否可能,但一个简单的解决方法是回退到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;
}

【讨论】:

  • 如果 C++ 不允许这样做对我来说会很奇怪。不过还是谢谢你的回答:)
猜你喜欢
  • 2014-12-31
  • 2016-09-15
  • 1970-01-01
  • 2019-10-16
  • 1970-01-01
  • 2019-08-06
  • 2014-11-02
  • 2020-11-13
  • 1970-01-01
相关资源
最近更新 更多