当存在冲突符号时使用一个或多个名称空间?

时间:2013-10-10 11:04:29

标签: c++ namespaces

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

namespace library1
{
  void function1();
}

namespace library1_sublibrary1
{
  void function1();
}

而不是

namespace library1
{
  void function1();

  namespace sublibrary1
  {
    void function1();
  }
}

我必须在第二种情况下完全限定符号,对吗?有没有具体的理由(超出个人品味)为什么一个人应该优先考虑另一个?

1 个答案:

答案 0 :(得分:1)

重复两条评论。

在两个版本之间(一个:两个独立的命名空间,两个:嵌套的命名空间),名称查找有一些差异。其中大部分都可以使用 using-declaration (例如using outer::function0;)或 using-directive (例如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();
    }
}

N.B。您还可以在another_outer的命名空间范围内放置 using-directive using-declaration ,但仍然存在一些差异:

2。停止不合格的查询

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

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。 ADL

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

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。特别是关于冲突的符号

如果outerouter::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
    }
}