C++不同名字空间的函数重载解析

父子名字空间中:
小作用域(子命名空间)会隐藏大作用域(父命名空间),无法在子命名空间和父命名空间构成重载。
但是可以在子命名空间引入父命名空间函数与子命名空间形成重载。
如下

void fun()
{
}
namespace a
{
    void fun(int x)
    {
    }
    namespace b
    {
        void fun(int x,int y)
        {
        }
        void test()
        {
            fun();//报错
            ::fun();//正确
            fun(1);//报错
            a::fun(1);//正确
            fun(1,3);//正确
        }
    }
}
int main()
{
    a::b::test();
    return 0;
}

即不同名字空间的签名相同的函数只有在引入到相同的作用域后,才可以形成重载。
如下:
代码快快1:

#include <cstdio>

void fun(int x)
{
    printf("g int\n");
}

namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    fun(1);//g int
    ::fun(1);//g int//未引入y的fun均使用全局的fun
    getchar();
}

命名空间具有隐藏功能。将使得该空间内的成员在声明该名字空间的作用域不可见。见代码块1

代码快快2:

#include <cstdio>

namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    using namespace y;//名字空间指令引入,当前作用域可见,定义在全局
    fun(1);           
    getchar();
}

如果要使其可见,可以通过名字空间指令using namespace xx使得xx在使用该指令的作用域内具有可见性,可以在引入指令下方的代码块使用该空间内的成员。但其作用域依然属于该名字空间定义所在作用域。见代码块2

代码快快3:

#include <cstdio>

void fun(int x)
{
    printf("g int\n");
}

namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    using namespace y;//名字空间指令引入到全局作用域
    //fun(1);//重载全局作用域的fun(int)冲突
    ::fun(1);
    y::fun(1);
    getchar();
}

名字空间指令using namespace xx使得该名字空间内的成员在使用using namespace xx后的代码块具有可见性。如果该名字空间所在作用域中存在相同签名的函数,则只引入名字空间(引入该函数)不会发生冲突,但是一旦使用该函数,则会发生冲突。见代码块3

代码快快4:

#include <cstdio>

namespace x
{
    void fun(void)
    {
        printf("void\n");
    }
}
namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    using namespace x;
    using namespace y;//名字空间指令引入到全局作用域
    fun();
    fun(1);//正常重载全局作用域的x::fun(void),y内的fun(int)
    getchar();
}

名字空间内成员的重载,需要名字空间内的成员引入到相同的作用域。见代码块4,main中使用名字空间指令后,在该指令以下代码块,x,和y中的fun均可见,且属于全局作用域,正常形成重载。

代码快快5:

#include <cstdio>

void fun(int x)
{
    printf("g int\n");
}

namespace x
{
    void fun(void)
    {
        printf("void\n");
    }
}
namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    using namespace x;
    using namespace y;//名字空间指令引入到全局作用域
    fun();
    fun(1);//冲突,因为该位置全局fun(int)和y::fun(int)都可见
    getchar();
}
1>e:\qt\test\test\test.cpp(27): error C2668: “fun”: 对重载函数的调用不明确
1>          e:\qt\test\test\test.cpp(3): 可能是“void fun(int)”
1>          e:\qt\test\test\test.cpp(17): 或       “void y::fun(int)”
1>          尝试匹配参数列表“(int)”时

继4此时如果全局又存在相同签名的函数,则同3,发生冲突,全局的fun和y中的fun在名字空间指令以下代码块都可见,都属于全局,且签名相同,冲突。见代码块5

代码快快6:

#include <cstdio>

void fun(int x)
{
    printf("g int\n");
}

namespace x
{
    void fun(void)
    {
        printf("void\n");
    }
}
namespace y
{
    void fun(int x)
    {
        printf("int\n");
    }
}
int main()
{
    using namespace x;
    using namespace y;//名字空间指令将x,y的成员引入到全局作用域
    fun();
    y::fun(1);
    ::fun(1);

    using x::fun;//将x::fun引入到当前局部作用域
    //fun(1);//error C2660: “x::fun”: 函数不接受 1 个参数,即该局部作用域内只有x::fun(void)被引入
    fun();

    getchar();
}

可以通过名字空间声明将该名字空间内的成员引入当前局部作用域,由于小作用域隐藏大作用域,则只有引入到该局部作用域的可见。见代码块6,全局的将被隐藏,导致fun(1)找不到定义。

总结:
名字空间引入指令:
using namespace xx;
将名字空间内的所有成员释放到其定义坐在作用域。
名字空间成员声明:
using xx::yy;
将名字空间内的单个成员释放到当前局部作用域。

名字空间内成员函数重载条件:
首先要将成员释放(具有可见性)到相同作用域。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值