1

据我了解,函数解析是从内部范围到外部范围。因此,在下面的示例中,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()}
}

因此,明确声明命名空间是安全且良好的做法,还是这种情况不够频繁,不足以证明额外的冗长是合理的?

4

1 回答 1

0

对于函数,我建议一般避免命名空间限定,除非需要防止实际或潜在的歧义。这在通用(模板)代码中特别有价值,因为命名空间限定抑制了依赖于参数的查找。允许实际类提供的函数可以产生更好的代码,有时可以避免损坏。例如:

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'non-throwing swap()。最好exchange()写成using std::swap; swap( lhs, rhs);

于 2013-06-14T23:30:31.747 回答