在工作,我们经常会引入第三方库,偶尔会碰到同名的函数和类型,造成编译冲突的问题。一般我们可以使用命名空间,例如
#include <iostream>
#include <iostream>
using namespace std;
namespace S1
{
void foo()
{
cout << "S1::foo()\n";
}
}
namespace S2
{
void foo()
{
cout << "S2::foo()\n";
}
}
using namespace S1;
int main()
{
foo();
S2::foo();
system("pause");
return 0;
}
结果:
在c++11中增强了命名空间的特性,提出了内联命名空间的概念 ,内联命名空间能够把空间内的函数和类型导出到父命名空间中,这样即使不指定子命名空间也可以使用其空间内的函数和类型了。
假设计算器类,提供了一个求和函数 long long Sum(int a,int b);突然某天加入了新特性,需要升级接口。有些客户需要升级,有些客户担心稳定性,而不愿意升级,还想用原来的接口,那我们就可以用下面的方法来解决该问题。
原来:
namespace Parent
{
long long Sum(int a, int b)
{
printf("Parent:%d + %d = %d\n",a,b,a+b);
return a + b;
}
}
修改:
使用老接口(不愿意更新的用户)
namespace Parent
{
inline namespace V0
{
long long Sum(int a, int b)
{
printf("Parent:%d + %d = %d\n", a, b, a + b);
return a + b;
}
}
namespace V1
{
long long Sum(int a, int b)
{
printf("V1:%d + %d = %d\n", a, b, a + b + 10);
return a + b + 10;
}
}
}
using namespace Parent;
int main()
{
int c = Sum(10, 20);
printf("c = %d\n",c);
system("pause");
return 0;
}
结果:
使用新的接口(愿意更新的用户)
namespace Parent
{
namespace V0
{
long long Sum(int a, int b)
{
printf("Parent:%d + %d = %d\n", a, b, a + b);
return a + b;
}
}
inline namespace V1
{
long long Sum(int a, int b)
{
printf("V1:%d + %d = %d\n", a, b, a + b + 10);
return a + b + 10;
}
}
}
using namespace Parent;
int main()
{
int c = Sum(10, 20);
printf("c = %d\n",c);
system("pause");
return 0;
}
结果:
可以看到应用端无需该代码,底层库只需要改变inline的位置即可!