【发布时间】:2020-05-16 16:47:14
【问题描述】:
我遇到了一对不寻常的编译器警告,它们似乎相互矛盾。这是我写的代码:
#include <functional>
#include <iostream>
namespace {
std::function<void()> callback = [] {
void theRealCallback(); // Forward-declare theRealCallback
theRealCallback(); // Invoke theRealCallback
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
callback();
}
换句话说,我在一个未命名的命名空间中定义了一个 lambda 函数,该函数前向声明了一个稍后在该未命名的命名空间中定义的函数。
当我使用 g++ 7.4.0 (Ubuntu 7.4.0-1ubuntu1~18.04.1) 编译这段代码时,我收到以下两个警告:
CompilerWarningsNamespace.cpp:6:10: warning: ‘void {anonymous}::theRealCallback()’ used but never defined
void theRealCallback();
^~~~~~~~~~~~~~~
CompilerWarningsNamespace.cpp:10:8: warning: ‘void {anonymous}::theRealCallback()’ defined but not used [-Wunused-function]
void theRealCallback() {
^~~~~~~~~~~~~~~
这很奇怪,因为第一个警告说我正在使用一个函数但没有定义它,而第二个警告说我正在定义一个函数但没有使用它。
运行这个程序确实会产生输出
theRealCallback was called.
程序正常终止。
有趣的是,如果我不使用未命名的命名空间,而是为命名空间命名,这些警告就会消失,如下所示:
#include <functional>
#include <iostream>
namespace NamedNamespace {
std::function<void()> callback = [] {
void theRealCallback();
theRealCallback();
};
void theRealCallback() {
std::cout << "theRealCallback was called." << std::endl;
}
}
int main() {
NamedNamespace::callback();
}
修改后的代码和原始代码一样,打印出一条消息,指出调用了theRealCallback。
有人可以解释为什么我会收到这些警告吗?我的猜测是,这与 lambda 函数中函数的前向声明有关,因为它被解释为出现在未命名命名空间中的后一个函数之外的东西,但如果是这种情况,我不确定我看到为什么最后会出现这个链接以及为什么我会收到这些警告。
【问题讨论】:
-
您不能在 lambda 中转发声明 theRealCallback()。将它移到上面,它应该可以工作。
-
我早上回来。你的帖子最有趣。重量级人物会介入并解决这个问题。我有一种感觉,你的编译器正在原谅它不应该做的事情。但是没有做律师的事......晚安。
标签: c++ lambda g++ compiler-warnings unnamed-namespace