c++ 如何结交本地班的函数朋友?

zxlwwiss  于 2023-05-08  发布在  其他
关注(0)|答案(4)|浏览(104)

请阅读代码以了解问题:

#include <iostream>

void fun(int value)
{
    //starts local class definition
    class test
    {
        int x;
    public:
        test(int a) : x(a) {}
        void display() const
        {
            std::cout << "x = " << x << std::endl;
        }
    };
    //end of the definition
    test t1(value);
    t1.display();
    //if we write the statement t1.x=100; here .It will give us an error
    //because we can not access the private members from the enclosing function
    //now what should I do if I want to access the private members of the test class from fun function
}
int main()
{
    fun(5);
}

我应该把这个有趣的函数作为本地类的朋友(测试)吗?我在阅读一本书,据说我们可以通过将封闭函数声明为friend来实现这一点。现在我的问题是,我不知道如何使封闭函数成为局部类的朋友。请告诉我,我该怎么做。

czq61nw1

czq61nw11#

我应该把这个有趣的函数作为本地类的朋友吗(测试)
不清楚你是否应该……避免破坏私有成员提供的封装通常是一个好主意。或者相反,如果不需要封装,那么成员是公共的可能会更简单。但让我们考虑一下你是否可以...
标准说(引用最新草案):
[同学.朋友]
如果一个友元声明出现在局部类([class.local])中,并且指定的名称是一个非限定名称,则查找前面的声明**,而不考虑最内层非类作用域之外的作用域**。对于友元函数声明,如果没有事先声明,则程序是病态的。...
如果我正确地解释了这个法律术语,那么在fun的函数体之外,没有任何非限定名称可以被查找。据我所知,fun的声明本身不在这个范围之内。然而,据我所知,没有什么可以阻止你重新声明这个函数:

void fun(int value)
{
    void fun(int); // (re)declaration within innermost enclosing non-class scope

    class test
    {
        friend void fun(int); // the friend declaration

这在Clang和MSVC中似乎可以工作,但不幸的是在GCC中不行,GCC仍然不允许访问私有成员。这可能是一个GCC bug。
另一种选择是用限定名声明朋友:

class test
{
    friend void ::fun(int); // qualified name

在这种情况下,上述限制将不适用。不幸的是,GCC也不接受这一点,并且在没有本地重新声明的情况下会产生一个诊断:
错误:友元声明'void fun(int)'在局部类中没有预先的局部声明
这看起来像是一个单独的bug,无论声明::fun还是任何其他限定函数名作为友元,它都会重现。我发现了一个现有的bugreport:https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69410

h79rfbju

h79rfbju2#

限定调用friend void ::fun(int);是一种方法:

void fun(int value)
{
    //starts local class definition
    class test
    {
        friend void ::fun(int);
        int x;
    public:
        test(int a)
        {
            x=a;
        }
        void display()
        {
            std::cout << "x = " << x << std::endl;
        }

    };
    //end of the definition
    test t1(value);
    t1.display();
    t1.x = 42;
    t1.display();
}

Demo
请注意,一些旧版本的g++拒绝了它。

iq3niunx

iq3niunx3#

首先声明函数

void fun(int);

然后在课堂上:

public:
friend void ::fun(int  );
mpbci0fu

mpbci0fu4#

请注意,这个bug现在已经在GCC中修复,并向后移植到版本10及以上。

相关问题