【问题标题】:How to declare a global-scope function a friend to a namespaced class?如何将全局范围函数声明为命名空间类的朋友?
【发布时间】:2021-02-23 21:19:19
【问题描述】:

以下代码在namespace Namespace 中定义class Foo

// main.cpp
#include <csignal>

namespace Namespace
{

class Foo
{
private:
  void doSomething() {};

friend void func( union sigval );
};

}

static Namespace::Foo foo;

void func( union sigval sv ) {
  (void)sv;
  foo.doSomething();
}

我想让void func( union sigval ) 成为这个类的朋友,以便它可以调用私有函数。 执行此操作的正确语法是什么?以上失败并出现以下错误

$ g++ --version && g++ -g ./main.cpp
g++ (Debian 6.3.0-18+deb9u1) 6.3.0 20170516
Copyright (C) 2016 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

./main.cpp: In function ‘void func(sigval)’:
./main.cpp:22:19: error: ‘void Namespace::Foo::doSomething()’ is private within this context
   foo.doSomething();
                   ^
./main.cpp:11:8: note: declared private here
   void doSomething() {};
        ^~~~~~~~~~~

这个变化...

friend void ::func( union sigval );

...导致此错误:

$ g++ -g main.cpp
main.cpp:13:34: error: ‘void func(sigval)’ should have been declared inside ‘::’
 friend void ::func( union sigval );
                                  ^

【问题讨论】:

    标签: c++ namespaces friend friend-function


    【解决方案1】:

    您可以仅使用 :: 引用全局范围。所以你的朋友声明可以是:

    friend void ::func( union sigval );
    

    但不要忘记在类中引用该函数之前先声明该函数!

    所以在全局范围内你需要:

    void func( union sigval );
    

    在类声明之前。

    编译示例:https://ideone.com/hDHDJ8

    【讨论】:

    • 我不明白为什么需要前向声明。当func 也在Namespace godbolt.org/z/YvWKzs 中时不需要它
    • 如果一个类声明了一个没有命名空间限定符的友元函数,并且该函数尚未声明,那么该函数将在与该类相同的命名空间中声明。要通过名称引用命名空间限定的全局函数,它必须已经声明。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-12-03
    • 2011-01-15
    • 1970-01-01
    • 1970-01-01
    • 2012-05-03
    • 1970-01-01
    相关资源
    最近更新 更多