首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带有内联命名空间的API版本控制

带有内联命名空间的API版本控制
EN

Stack Overflow用户
提问于 2020-04-21 09:12:03
回答 1查看 266关注 0票数 1

我想在不破坏用户的情况下,在库的API (西斯塔)中引入一个突破性的更改。因此,我希望为客户端提供一种以自己的速度迁移到新API的方法。为此,我想使用内联名称空间。基本思想非常简单,您可以为旧版本引入一个namespace v1,为新版本引入一个inline namespace v2 (或者相反)。在https://foonathan.net/2018/11/inline-namespaces/中很好地描述了这一点。当您想要引入另一个突破性的更改,即namespace v3时,麻烦就开始了。让我们有一些示例代码作为进一步讨论的基础:

代码语言:javascript
复制
namespace v1 {
    int foo(); // old version of foo
}

inline namespace v2 {
    std::string foo(); // new, incompatible version of foo
    int bar(); // old version of bar
}

namespace v3 {
    std::string bar(); // new, incompatible version of bar
}

现在,如果我想将默认的API版本更新为v3,即使v3版本的bar()在默认情况下可用,我可以创建namespace v3 inline。我们陷入了两难境地:如果我只使用v3 inline,我就会中断已经迁移到使用最新的v2版本的foo()的客户机(因此使用它时没有名称空间限定符)。如果我同时创建了v2v3 inline,以便所有函数的最新版本都可以在全局(库)命名空间中访问,那么在v3::bar()v2:bar()之间就会出现歧义。如果我将v2::foo()移动到v3,就会破坏刚刚开始迁移到v2::foo()并使用完全限定名(::v2::foo())的客户端。另一个选项是重新声明名称空间中与最新API版本相对应的所有最新版本的函数,并且只声明该inline。这是大量的重复和一些额外的生成代码。有没有更优雅的解决方案?

有人还建议我只将所有符号的最新版本导出到using v2::bar (等等)到最新的内联命名空间中。然而,据我所知,这破坏了ADL。

EN

回答 1

Stack Overflow用户

发布于 2020-04-23 16:29:48

最后,我解决了一个不像我希望的那样好和优雅的解决方案,但它很简单,而且很有效。我的解决方案是为每个重大更改引入两个新的api版本。就我从问题中得出的例子而言,我做了以下工作:

代码语言:javascript
复制
namespace v1 {
    int foo(); // old version of foo
}

inline namespace v2 {
    std::string foo(); // new, incompatible version of foo

namespace v3 {
    int bar(); // old version of bar
}

inline namespace v4 {
    std::string bar(); // new, incompatible version of bar
}

奇数版本代表已更改符号的废弃版本,偶数版本代表其新版本。这个系统是可扩展的、简单的和健壮的,但是它有点不直观,而且绝对不优雅。我已经设置了预处理器宏,允许客户端选择默认的"api版本“。例如,如果客户端尚未准备好使用最新的API,则可以选择after 3,在此之后,名称空间v2和v3将是内联的。在迁移到最新的API之后,它们可以将API版本提高到4,这将导致上述状态。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/61339880

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档