C ++内联命名空间的基本原理是源代码和二进制兼容性(参见N2535中链接的Herb Sutter论文),但我找不到好的例子引入内联命名空间时,保持现有库的二进制兼容性,或者是否可能。
(有关更多信息和源兼容性示例,请参阅this question)
(为解决相关问题,使用内联命名空间引入不兼容性,请参阅this question)
如果这是我们当前的库(例如mylib.dll),它与客户共享并且需要稳定:
struct ModelA
{
/* (...) lots of stuff */
};
struct ModelB
{
/* (...) lots of stuff */
};
我们是否可以使用内联命名空间来引入新版本的结构/类而不会破坏客户端(即仅替换共享库文件(mylib.dll),不需要重新编译)?
inline namespace mylib
{
inline namespace v1
{
struct ModelA
{
/* (...) lots of stuff */
};
} // end namespace v1
namespace v2
{
struct ModelA
{
/* (...) lots of stuff + newstuff */
};
} // end namespace v2
struct ModelB
{
/* (...) lots of stuff */
};
} // end namespace mylib
如果没有,它是否可以在没有封闭内联命名空间mylib的情况下工作?
答案 0 :(得分:2)
不是你问题的答案,但可能会得到答案。
使用两个简单的来源在gcc 4.8.2
下进行测试:
namespace n1
{
void f1 (int);
inline namespace n2
{
void f2 (int);
}
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
没有内联命名空间:
namespace n1
{
void f1 (int);
void f2 (int);
}
void f (int x)
{
n1::f1(x);
n1::f2(x);
}
然后使用objdump -t
检查编译对象文件中符号的错位名称。
第一个版本的结果(带有内联命名空间的):
_ZN2n12f1Ei
_ZN2n12n22f2Ei
第二个版本(不带内联命名空间):
_ZN2n12f1Ei
_ZN2n12f2Ei
您可以看到错误的f2
名称不同(第一个包含n2
命名空间的名称)。这意味着如果您使用gcc
,则不能仅使用带有内联命名空间的新库替换您的库。我不希望其他一些编译器会以另一种方式执行它(保存与内联命名空间的二进制兼容性)。