【问题标题】:When is a namespace::function() declaration useful?namespace::function() 声明何时有用?
【发布时间】:2018-05-17 11:34:55
【问题描述】:

单个文件示例

这是一个使用命名空间的简单程序。

#include <iostream>

namespace foo {
    void hello();
}

void foo::hello() {
    std::cout << "hello\n";
}

void foo::hello(); // Why is this syntax allowed? When is it useful?

int main() {
    foo::hello();
}

该程序编译良好并产生预期的输出。

$ ./a.out
hello

我想知道void foo::hello(); 声明何时有用?在这个程序中,显然这个声明是多余的。但是既然存在这种语法,那它在其他一些场景中一定有用吗?

双文件示例

这里有一个例子表明单独的void foo::hello(); 声明是没有用的。

// foo.cpp
#include <iostream>

namespace foo {
    void hello();
}

void foo::hello() {
    std::cout << "foo::hello\n";
}
// main.cpp
void foo::hello(); // This does not work!

int main()
{
    foo::hello();
}

尝试编译以上两个文件会出现以下错误:

$ clang++ foo.cpp main.cpp
main.cpp:1:6: error: use of undeclared identifier 'foo'
void foo::hello();
     ^
main.cpp:5:5: error: use of undeclared identifier 'foo'
    foo::hello();
    ^
2 errors generated.

在上述示例中修复main.cpp 的唯一方法似乎是包含namespace 声明:

// main.cpp - fixed
namespace foo {
    void hello();
}

void foo::hello(); // But now this is redundant again!

int main()
{
    foo::hello();
}

所以在我们正确编译这段代码后,void foo::hello(); 声明似乎又是多余的了。在任何情况下,这样的声明会发挥有用的作用吗?

【问题讨论】:

  • 例如,当另一个命名空间中存在同名函数时......这可能发生在大型项目中或使用 API 时
  • @JHBonarius 我总是可以通过指定命名空间来指定我想调用哪个hello(),例如foo::hello();bar::hello(); 在编写实际调用时。 void foo::hello(); 声明的目的是什么?我认为它在选择我想要的命名空间 hello() 方面没有任何作用,因为我在调用 hello() 时指定了自己。
  • 哦,等等:您的问题可能是关于 extra 声明的。我认为这是函数原型:那么它是多余的。
  • @LoneLearner 而不是打开命名空间写声明和关闭命名空间你可以写“myns::myfoo”。它只是节省了几次击键
  • @bartop 我不确定你的意思。必须有一个声明,用namespace &lt;name&gt; { 打开命名空间并用} 关闭它,否则它似乎不起作用:ideone.com/xVqfsg 你能发布你的意思的实际工作代码吗?

标签: c++ function namespaces declaration


【解决方案1】:

在 C++ 中的大多数情况下,对于任何可以在没有定义的情况下声明或可以完全定义的事物,该事物的声明或定义都可以出现在所有相同的上下文中。所以这可能只是保持模式一致的一种方式。

C++ 标准不会特意禁止那些是其他规则的逻辑结果但只是无用的事情,只要它相当清楚如果有人这样做会发生什么。如果它确实添加了这些限制,那会给编译器编写者带来额外的工作而没有真正的好处。

【讨论】:

    【解决方案2】:

    来自[basic.def]/1

    一个声明可以在翻译单元中引入一个或多个名称,或者重新声明先前声明引入的名称。如果是,则声明指定这些名称的解释和属性。

    允许这样的代码

    #include <iostream>
    
    void foo();
    void foo();
    void foo();
    void foo();
    void foo();
    
    int main()
    {
        foo();
    }
    
    void foo() { std::cout << "foo()"; }
    

    有效。一个函数有多个声明没有坏处,只要我们只有一个定义,就不会造成问题。


    另一个例子是你有一个全局函数,你想成为多个类的朋友。您将在每个类头中包含该函数原型,以便您可以将其作为朋友,然后您将在主源文件中包含所有这些类头。所以

    A.h
    void foo();
    struct A { friend void foo(); }
    
    B.h
    void foo();
    struct B { friend void foo(); }
    
    main.cpp
    #include "A.h"
    #include "B.h"
    
    ...
    

    这将被转换为

    main.cpp
    void foo();
    struct A { friend void foo(); }
    
    void foo();
    struct B { friend void foo(); }
    
    ...
    

    所以我们希望这是合法的。

    【讨论】:

      猜你喜欢
      • 2023-04-01
      • 1970-01-01
      • 2020-06-08
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-10-02
      相关资源
      最近更新 更多