【问题标题】:g++ issues incomprehensible warning [duplicate]g ++发出难以理解的警告[重复]
【发布时间】:2019-10-05 23:08:10
【问题描述】:

system.h:

#include <iostream>

namespace ss
{
  class system
  {
  private:
    // ...
  public:
    // ...
    friend std::ostream& operator<< (std::ostream& out, const system& sys);

   };
}

system.cpp:

#include "system.h"

std::ostream& ss::operator<< (std::ostream& out, const ss::system& sys)
  {
    // print a representation of the ss::system
    // ...
    return out;
  }

使用 g++ 8.30 编译上述代码会产生以下输出:

[db@dbPC test]$ LANG=en g++ -Wall -Wextra system.cpp
system.cpp:2:15: warning: 'std::ostream& ss::operator<<(std::ostream&, const ss::system&)' has not been declared within 'ss'
 std::ostream& ss::operator<< (std::ostream& out, const ss::system& sys)
               ^~
In file included from system.cpp:1:
system.h:11:26: note: only here as a 'friend'
     friend std::ostream& operator<< (std::ostream& out, const system& sys);
                          ^~~~~~~~
system.cpp: In function 'std::ostream& ss::operator<<(std::ostream&, const ss::system&)':
system.cpp:2:68: warning: unused parameter 'sys' [-Wunused-parameter]
 std::ostream& ss::operator<< (std::ostream& out, const ss::system& sys)
                                                  ~~~~~~~~~~~~~~~~~~^~~

编译器告诉我,operator&lt;&lt; 函数没有在命名空间ss 中声明。但是它在该命名空间中声明的。

我也尝试用clang++ 编译它。 clang 只抱怨未使用的参数,而不是抱怨我不明白的“不在命名空间内”问题。

g++ 警告的原因是什么?这是一个错误的警告吗?

版本:

g++ (GCC) 8.3.0
clang version: 8.00 (tags/RELEASE_800/final)

【问题讨论】:

  • 好友被删除了怎么办?
  • friend 声明不会使名称在命名空间中通过非限定查找可找到(技术上它在命名空间中,但尚未在那里声明)
  • @M.M 但ss::operator&lt;&lt;(...) 不合格吗?同意 un-qualified 不会找到它(ADL 除外),但是这里我们有一个限定的定义,所以应该没有警告。
  • 我现在链接到涵盖该主题的其他问题。恕我直言,gcc 警告非常严重,默认情况下应该关闭,代码 per se 没有任何问题,实际上我认为您的代码是一种很好的做法。但是您可以使用额外的声明来抑制警告,如 arsdever 的回答中所示
  • 感谢您的帮助,我摆脱了警告:D!

标签: c++ gcc operator-overloading language-lawyer friend


【解决方案1】:

您只是错过了在namespace 中声明operator &lt;&lt;

尝试以下方法:

namespace ss
{
  std::ostream& operator << (std::ostream& out, const system& sys);
  class system
  {
  private:
    // ...
  public:
    // ...
    friend std::ostream& operator<< (std::ostream& out, const system& sys);

   };
}

// in cpp

namespace ss
{
  std::ostream& operator << (std::ostream& out, const system& sys)
  {
    // the body
  }
}

【讨论】:

  • 我想知道在命名空间之外定义函数是什么意思?我的意思是这完全是错误的还是只是一个额外的警告?
  • 有一种人只在.cpp文件中做函数定义。我也是这样的人。
  • 我在哪里删除了ss::?你的意思是声明还是定义?请注意,我已经在 namespace ss 里面写了,不再需要在函数前面写 ss::
  • @arsdever,我只是个笨蛋。我把 ss 误认为是类名,并且您将定义包含在命名空间中,而不是像 OP 那样限定命名空间,所以没有区别。
  • 这是代码语义的巨大变化。现在,任何可隐式转换为system 的参数都可能导致以a&lt;&lt;b 形式的表达式调用此函数。编译器错误消息也可能被污染,因为此函数参与了失败的重载解决方案。它应该在 .cpp 文件中声明,而不是在头文件中。
猜你喜欢
  • 2019-09-06
  • 2021-03-11
  • 1970-01-01
  • 1970-01-01
  • 2012-05-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多