Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/144.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ C++;名称空间规范是多余的还是有用的?_C++_Coding Style_Namespaces - Fatal编程技术网

C++ C++;名称空间规范是多余的还是有用的?

C++ C++;名称空间规范是多余的还是有用的?,c++,coding-style,namespaces,C++,Coding Style,Namespaces,据我所知,函数解析是从内部作用域到外部作用域的。因此,在下面的示例中,在这两种情况下都将执行MyNamespace::foo() foo() {} namespace MyNamespace { void foo() {} void bar() {foo()} } foo() {} namespace MyNamespace { void foo() {} void bar() {MyNamespace::foo()} // redundant, or safe

据我所知,函数解析是从内部作用域到外部作用域的。因此,在下面的示例中,在这两种情况下都将执行
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()}
}

因此,明确声明名称空间是安全和良好的做法,还是这种情况不够频繁,不足以证明额外的详细性?

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

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 );
    }
}
名称空间foo{
样板
结构Ctnr{
Ctnr();
水泥净浆(水泥净浆常数&);
Ctnr和操作员=(Ctnr常量和);
~Ctnr();
// ...
好友无效交换(Ctnr&,Ctnr&);//不抛出。
};
}
名称空间栏{
样板
无效交换(T&lhs、T&rhs){
标准:交换(左侧、右侧);
}
静态foo::Ctnr状态;
无效集状态(foo::Ctnr新状态){
//调用std::swap,这可能引发并损坏状态:
交换(州、新州);
}
}

如果使用ADL编写了
bar::exchange()
bar::set_state()
将使用
foo
的非抛出
swap()
。最好使用std::swap将
exchange()
写成
;交换(左、右)

它是安全的,主要用于可能出现的
歧义的情况(您提供的第二种情况,或具有相同名称但属于不同名称空间的类)。这种“额外的冗长”也是可读性和可追踪性的保证。例如,您经常会看到
std::string
。我创建名称空间的频率不够高,因此不会有强烈的意见,但我认为您描述的情况非常罕见,可以忽略。您需要一个丢失的标识符和一个在同一范围内定义了相同名称的兼容符号,这样做的可能性很小。使用来自外部的命名空间可以提供好的文档,如果没有别的,但是在命名空间本身,我会认为它是噪声。