1

使用两个命名空间的优缺点是什么,例如

namespace library1
{
  void function1();
}

namespace library1_sublibrary1
{
  void function1();
}

代替

namespace library1
{
  void function1();

  namespace sublibrary1
  {
    void function1();
  }
}

在第二种情况下,我必须完全限定符号,对吗?是否有任何具体原因(超出个人喜好)为什么应该优先考虑另一个?

4

1 回答 1

1

重复两条评论。

在两个版本之间(一:两个独立的命名空间,二:嵌套的命名空间),名称查找存在一些差异。其中大部分可以通过使用声明(例如using outer::function0;)或使用指令(例如using namespace library1;)来克服,但有些不能。

1.内部命名空间内的非限定查找

#include <iostream>

namespace outer
{
    void function0() { std::cout << "outer::function0" << std::endl; }

    namespace inner
    {
        void test0()
        {
            function0(); // finds outer::function
        }
    }
}

namespace another_outer
{
    void test0_1()
    {
        // either
        using namespace outer;
        // or
        using outer::function0;

        function0();
    }
}

注意,您也可以将using-directiveusing-declaration放在命名空间范围内another_outer,但仍有一些区别:

2.停止不合格的查找

一旦找到名称,不合格的查找就会在一个范围内停止(然后不搜索外部范围)。这可用于隐藏其他范围的功能。这是与此相关的问题的示例;也看到这个答案

void function1() { std::cout << "::function1" << std::endl; }

namespace another_outer
{
    void function1() { std::cout << "another_outer::function1" << std::endl; }
}

namespace outer
{
    namespace inner
    {
        void function1() { std::cout << "outer::inner::function1" << std::endl; }
    }

    void test1()
    {
        function1(); // finds ::function1

        {
            using namespace inner;
            function1(); // finds (only) outer::inner::function1
        }

        {
            using namespace another_outer;
            //function1(); // finds both ::function1 and another_outer::function1
            // error: ambiguous call
        }
    }
}

3. 日常生活

这与两个变体之间的差异无关,而是解决“在第二种情况下我必须完全限定符号,对吗?”。当您不限定函数调用中的函数名称时,会发生与参数相关的查找。它在与参数关联的命名空间(和类)中查找函数的名称。

namespace outer
{
    struct ADL {};
    void function2(ADL&) { std::cout << "outer::function2" << std::endl; }

    namespace inner
    {
        void function2(ADL const&);
        void test2()
        {
            ADL x;
            function2(x); // finds both outer::function2
                          // and outer::inner::function2
            // overload resolution selects outer::function2
        }
    }
}

int main()
{
    outer::ADL x;
    function2(x); // finds outer::function2
    outer::inner::test2();

    // other tests:
    outer::inner::test0();
    outer::test1();
}

4. 特别是关于冲突的符号

如果您有两个相同的函数(返回类型除外),outer并且outer::inner在某个调用中找到了两者,则该调用将是模棱两可的。但是不合格的查找可能只能找到其中之一:

namespace outer
{
    void function3() { std::cout << "outer::function3()" << std::endl; }

    namespace inner
    {
        void function3()
        { std::cout << "outer::inner::function3()" << std::endl; }

        void test3()
        {
            function3(); // only finds outer::inner::function3
        }
    }

    void test3_1()
    {
        using namespace inner;
        //function3(); // finds both outer::function3
                       // and outer::inner::function3
        // error: ambiguous call

        using inner::function3;
        function3(); // finds (only) outer::inner::function3
    }
}

namespace another_outer
{
    void function3() { std::cout << "another_outer::function3" << std::endl; }

    void test3_1()
    {
        using namespace outer;
        function3(); // still only finds another_outer::function3

        using outer::function3;
        function3(); // only finds outer::function3
    }
}
于 2013-10-11T15:44:17.400 回答