首页 > 解决方案 > 为什么 g++ 不能编译嵌套的友元类用法,而 clang++ 可以?

问题描述

据我所知,friend class Foo在一个类Bar中可以Foo访问Bar. 我写了下面的代码,它通过编译clang++ main.cc -std=c++14,也c++11。但是g++不能在两个版本中。

#include <iostream>

class Foo {
    friend std::ostream& operator<<(std::ostream& os, const Foo& foo) {
        return os << foo.bar.data;
    }

   public:
    Foo() = default;

    class Bar {
        friend class Foo;
        Bar(int _data = 0) : data(_data) {}

       private:
        int data;
    };

   private:
    Bar bar;
};

int main() {
    Foo foo;
    std::cout << foo << std::endl;
    return 0;
}

一开始我以为可能是操作符比较特殊,所以我写了一个测试函数friend void test(const Foo &foo) { std::cout << foo.bar.data << std::endl; }而不是std::ostream & operator. 结果与上述相同。

#include <iostream>

class Foo {
    friend void test(const Foo& foo) {
        std::cout << foo.bar.data << std::endl;
    }

   public:
    Foo() = default;

    class Bar {
        friend class Foo;
        Bar(int _data = 0) : data(_data) {}

       private:
        int data;
    };

   private:
    Bar bar;
};

int main() {
    Foo foo;
    test(foo);
    return 0;
}

g++替换前的结果:

main.cc: In function ‘std::ostream& operator<<(std::ostream&, const Foo&)’:
main.cc:5:30: error: ‘int Foo::Bar::data’ is private within this context
    5 |         return os << foo.bar.data;
      |                              ^~~~
main.cc:16:13: note: declared private here
   16 |         int data;
      |             ^~~~

后:

main.cc: In function ‘void test(const Foo&)’:
main.cc:5:30: error: ‘int Foo::Bar::data’ is private within this context
    5 |         std::cout << foo.bar.data << std::endl;
      |                              ^~~~
main.cc:16:13: note: declared private here
   16 |         int data;
      |             ^~~~

我想知道这是否是一个特殊场合g++没有实现clang++,或者在嵌套类中时事情很特别。

标签: c++c++14inner-classes

解决方案


推荐阅读