模板实例化期间第二次通过名称查找的静态命名空间与匿名命名空间的差异



自从停止将static用于辅助函数以来,我一直long支持匿名命名空间,它具有处理类型、变量和模板以及函数的优势。

然而,当我用包装器模板替换对函数的调用时,却没有找到函数,这让我很惊讶。请参阅代码https://godbolt.org/z/GrojceqGx与我的项目相匹配的编译器和选项。

#include <utility>
//#define WORKING
class C {};
template <typename Left, typename Right>
auto wrapper (Left&& left, Right&& right, const char* name)
{
return foo (std::forward<Left>(left),std::forward<Right>(right));
}
#ifdef WORKING
static
void foo (C& left, int right)
{
// compiles when using static function
}
#else
namespace {
void foo (C& left, int right)
{
// fails to compile in anonymous namespace
}
}
#endif
void sample()
{
C x;
wrapper (x, 17, "call 1");
}

为什么wrapper的实例化在static时看到foo,而在匿名命名空间中时却看不到?实例化的点在这个翻译单元中,无论哪种方式都在同一个位置。

因为匿名命名空间完全是另一个命名空间,信不信由你。而不是全局命名空间。

当您使用static时,ADL会找到foo。因为现在foo正确地位于C的关联命名空间(全局命名空间(中。

然而,它将适用于内联匿名命名空间,即

inline namespace { }

由于ADL被设计成可以很好地与内联名称空间配合使用。

最新更新