据我了解,函数解析是从内部作用域到外部作用域发生的。因此,在下面的示例中,MyNamespace::foo()
将在两种情况下执行。
foo() {}
namespace MyNamespace
{
void foo() {}
void bar() {foo()}
}
foo() {}
namespace MyNamespace
{
void foo() {}
void bar() {MyNamespace::foo()} // redundant, or safe and expressive?
}
但是,可能会出现这样一种情况,你打算调用MyNamespace::foo()
,但是因为你的MyNamespace::foo()
实际上并没有定义,定义的全局 foo()
被调用。
foo() {printf("I don't think you meant to call me...");}
namespace MyNamespace
{
//foo() {}
void bar() {foo()}
}
因此,显式声明命名空间是否安全和良好的做法,或者这种情况是否不够频繁以证明额外的冗长是合理的?
最佳答案
对于函数,我建议一般避免命名空间限定,除非需要防止实际或潜在的歧义。这在通用(模板)代码中特别有值(value),因为 namespace 限定抑制了参数相关的查找。允许实际类提供的功能可以产生更好的代码,有时还可以避免损坏。例如:
namespace foo {
template<typename T>
struct Ctnr {
Ctnr();
Ctnr( Ctnr const & );
Ctnr &operator=( Ctnr const & );
~Ctnr();
// ...
friend void swap( Ctnr<T> &, Ctnr<T> & ); // Does not throw.
};
}
namespace bar {
template<typename T>
void exchange( T &lhs, T &rhs ) {
std::swap( lhs, rhs );
}
static foo::Ctnr<string> state;
void set_state( foo::Ctnr<string> new_state ) {
// Calls std::swap, which may throw and corrupt state:
exchange( state, new_state );
}
}
如果bar::exchange<T>()
已使用 ADL 编写,bar::set_state()
会用 foo
的非抛swap()
.最好写成exchange()
作为using std::swap; swap( lhs, rhs);
关于C++ 命名空间规范是多余的还是有用的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17118304/