离线成员函数定义是不是需要完全限定的类名到全局范围?

Posted

技术标签:

【中文标题】离线成员函数定义是不是需要完全限定的类名到全局范围?【英文标题】:Is a fully qualified class name down to global scope ever required for out-of-line member function definitions?离线成员函数定义是否需要完全限定的类名到全局范围? 【发布时间】:2020-03-13 19:12:06 【问题描述】:

This 问题让我想知道在类外成员函数定义中完全限定类名(包括全局范围运算符)是否有用/有必要。

一方面,我以前从未见过这样做(而且正确执行此操作的语法似乎晦涩难懂)。另一方面,C++ 名称查找非常重要,因此可能存在极端情况。

问题:

有没有通过ReturnType (::Fully::Qualified::Class::Name::MemberFunctionName)(...) ... 引入类外成员函数定义的情况 会不同于ReturnType Fully::Qualified::Class::Name::MemberFunctionName(...) ... (没有全局范围 :: 前缀)?

请注意,成员函数定义必须放在包含类的命名空间中,因此this 不是有效示例。

【问题讨论】:

非常好奇投票者不喜欢这个问题的什么地方。欢迎反馈! 当定义被放置在与声明不同的命名空间时?这就是我对你链接的问题的想法 哎呀,没看小字;) @foreknownas_463035818 这也是我的想法,然后我尝试了它并意识到它不起作用,所以我写了这个问题(认为其他人也会想知道)。 【参考方案1】:

using-directive 可能会导致 Fully 在没有限定的情况下产生歧义。

namespace Foo 
    struct X 
    ;


using namespace Foo;
struct X 
    void c();
;

void X::c()   // ambiguous
void ::X::c()   // OK

【讨论】:

【参考方案2】:

如果一个人是受虐狂并且喜欢写这样的东西,这是必要的

namespace foo 
    namespace foo 
        struct bar 
            void baz();
        ;
    

   struct bar 
       void baz();
   ;

   void foo::bar::baz() 
   

   void (::foo::bar::baz)() 
   
 

当然可以在全局范围内将第二个重载写为foo::foo::bar::baz,但问题是这两个声明是否可以具有不同的含义。我不建议编写这样的代码。

【讨论】:

是的,这确实是一个有效的答案,甚至不需要using。很高兴突出显示不同的案例!【参考方案3】:

如果使用 using 指令,则代码可能会令人困惑。

考虑以下演示程序

#include <iostream>
#include <string>

namespace N1

    struct A
    
        void f() const;
    ;      


using namespace N1;

void A::f() const  std::cout << "N1::f()\n"; 

struct A

    void f() const;
;

void ::A::f() const  std::cout << "::f()\n"; 

int main() 

    N1::A().f();
    ::A().f();

    return 0;

所以为了便于阅读,这个限定名

void ::A::f() const  std::cout << "::f()\n"; 

精确显示函数的声明位置。

【讨论】:

以上是关于离线成员函数定义是不是需要完全限定的类名到全局范围?的主要内容,如果未能解决你的问题,请参考以下文章

如何将完全限定的类名映射到 Python 中的类对象?

重构 MFC 消息映射以包含完全限定的成员函数指针

PHP之namespace小记

C++ static 修饰符

如何在不使用类名作为范围的情况下获取类中成员函数的地址?

Jython 中的完全限定类名