C++ 命名空间设置为已使用,因为内部使用了一种类型?

C++ 命名空间设置为已使用,因为内部使用了一种类型?,c++,namespaces,C++,Namespaces,我刚注意到这个。我不知道为什么会出现这种情况,如果我使用一个名称空间中的一个元素,我不想在不使用名称空间的情况下访问任何其他元素。例如,这里的代码是有效的: namespace Test { struct Magic { int poof; }; struct Magic2 { int poof; }; int Alakazam(const Magic& m) { retu

我刚注意到这个。我不知道为什么会出现这种情况,如果我使用一个名称空间中的一个元素,我不想在不使用名称空间的情况下访问任何其他元素。例如,这里的代码是有效的:

namespace Test
{
    struct Magic
    {
        int poof;
    };

    struct Magic2
    {
        int poof;
    };

    int Alakazam(const Magic& m)
    {
        return m.poof;
    }

    int Alakazam(const Magic2& m)
    {
        return m.poof;
    }
};

using Magic = Test::Magic;

int main()
{

    Alakazam(Magic());        // valid
    Alakazam(Test::Magic2()); // valid

    Test::Alakazam(Magic()); // what i want to only be valid
    Test::Alakazam(Test::Magic2()); // this too
}

这背后有什么原因吗?规范是否规定这必须是真的?

正如immbis在评论中所建议的,这是由标准定义的:

3.4.2:参数相关名称查找

  • 当函数调用中的后缀表达式是非限定id时,通常情况下不会考虑其他名称空间 可以搜索非限定查找,并且在这些名称空间中, 命名空间作用域友元函数或函数模板声明不正确 否则,可能会发现可见。这些对搜索的修改 取决于参数的类型(对于模板 参数,模板参数的命名空间)

  • 如果您想击败这种mecanism,您必须像这样使用嵌套命名空间,但这很棘手:

    namespace Test
    {
        struct Magic
        {
            int poof;
        };
        struct Magic2
        {
            int poof;
        };
    
        namespace Test2 {   // use a nested namespace that will not be searched autoamtically 
            int Alakazam(const Magic& m)
            {
                return m.poof;
            }
    
            int Alakazam(const Magic2& m)
            {
                return m.poof;
            }
        } 
        using namespace Test2;  // but give some access to the enclosing namespace 
    };
    

    :那么,您的前两次呼叫将不再有效。但是,示例中的最后一个调用仍然是可能的:您不能阻止在命名空间之外使用完全限定名

    这被称为参数相关查找。
    poof
    对于PC变量名来说是一个非常好的主意吗?@EdHeal-它还有其他含义,尤其是在magic的上下文中。@EdHeal同性恋或变性变量没有错。为什么不使用Test::magic添加
    在最小范围内?这是同样的事情,但看起来没那么有趣。:)