了解带有命名空间污染的 TOTW 153 示例



在 TOTW 153 中声称在函数作用域中使用命名空间可能会在全局作用域中泄漏, 换句话说,他们声称这是:

namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
using namespace ::testing;
Sequence seq;  // ::testing::Sequence
WallTimer timer;  // ::WallTimer
}
}  // namespace
}  // namespace example
}  // namespace totw

大致相当于:

using ::testing::Expectation;
using ::testing::Sequence;
using ::testing::UnorderedElementsAre;
...
// many, many more symbols are injected into the global namespace
namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
Sequence seq; // ::testing::Sequence
WallTimer timer; // ::WallTimer
...
}
} // namespace
} // namespace example
} // namespace totw

所以我希望如果我这样做它会编译:

#include <gtest/gtest.h>
#include <gmock/gmock.h>
namespace totw {
namespace example {
namespace {
TEST(MyTest, UsesUsingDirectives) {
using namespace ::testing;
Sequence seq;  // ::testing::Sequence
}
}  // namespace
}  // namespace example
}  // namespace totw
Sequence s; //notice no testing::

它没有。所以我想知道我复制这个例子是错的,还是TOTW153的例子具有误导性?

我最好的猜测是,他们的例子是"错误的",因为他们声称大致等价的东西在某种意义上并不真正等同。

您是正确的,"转译"代码可能会导致人们认为您的最后一个片段应该有效。但这不是他们的意思。

使用::testing::Expectation等从TEST范围的角度添加到全局命名空间中。换句话说,只有在TEST范围内,转译的代码实际上与原始代码相同。在该范围之外没有任何影响,但它们列出的问题仍然是问题(除非您知道TEST范围的内容或任何涉及的命名空间的内容都不会更改(。换句话说,using在该TEST范围内的所有(现在和将来(符号与所有相关命名空间中的符号(现在和将来(之间引入了潜在的冲突。听起来不那么可怕,但从长远来看仍然会咬你。

最新更新