首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >C++11内联命名空间与将类型直接嵌入在封闭命名空间中的比较

C++11内联命名空间与将类型直接嵌入在封闭命名空间中的比较
EN

Stack Overflow用户
提问于 2017-04-14 23:57:23
回答 1查看 720关注 0票数 1

阅读和研究大量关于新的C++11特性--“内联命名空间”--我不明白这个特性的真正好处是什么。

我可以很容易地将定义在“内联命名空间”中的所有函数/类型直接放在封闭的名称空间中,并具有相同的结果。那么,在内联命名空间中放置函数/类型的真正动机是什么?对函数/类型进行分组?使用“内联命名空间”是否有与ADL相关的好处?我认为ADL的行为与对此“内联名称空间”有一个隐式“使用”指令一样。

EDIT1:

因此,我认为以下是关键的优势。假设一开始我们有:

代码语言:javascript
复制
namespace toplevel {
     // Users can use toplevel::MyType
     inline namespace current {
           class MyType {};
     } // inline namespace current
} // ns toplevel

现在,一些新的需求,我们需要一个新的版本,但保持旧的一个不变:

代码语言:javascript
复制
namespace toplevel {
     // Users can use toplevel::MyType
     // we can let the users know that we are going to deprecate it
     // in favor of toplvel::next::MyType
     inline namespace current {
           class MyType {};
     } // inline namespace current

     // Users can use toplevel::next::MyType
     namespace next {
           class MyType {};
     } // namespace next

} // ns toplevel

最后做这件事。将内联移动到"next“命名空间,使其成为默认名称空间。仍然允许用户访问“当前”,但使用的是明确的::current --即,这种方式: toplevel::current::MyType BTW --我的偏好甚至会将"current“重命名为"deprecated”。

代码语言:javascript
复制
namespace toplevel {
     // Users can still use it by referring
     // to toplevel::current::MyType
     namespace current {
           class MyType {};
     } // inline namespace current

     // Have this one the default one 
     // under toplevel
     // Users can use the new one this way: toplevel::MyType
     inline namespace next {
           class MyType {};
     } // namespace next

} // ns toplevel

听起来像是一个正确的场景吗?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2021-03-08 20:53:09

C++内联名称空间的主要动机确实涉及版本控制。除了问题的最后一句外,你的理解是正确的:

我的偏好甚至会将“当前”重命名为“不推荐”。

使用内联名称空间的整个想法是名称空间名称没有变化--相反,这个特性允许名称空间名称不需要更改;现有名称可以永远存在,而不需要对代码进行太多更改。

相反,在版本发布时(当我们过去认为“当前特性”现在变成了“弃用特性”时),名称空间名称可以保持不变,但它们的默认状态会被更新。

让我们在代码中看到这一点:

代码语言:javascript
复制
namespace MyProject {
    namespace Version1 {
        void BoringStableFunction() {...}
    }
    inline namespace Version2 {
        void BoringStableFunction() {...}
        void LatestAndGreatest(int x) {...}
    }
}

这个软件的客户可能最常使用它,只需调用MyProject::BoringStableFunction()MyProject::LatestAndGreatest(11),甚至不知道MyProject的两个不同版本。这样的方便是件好事。如果客户确实知道有两个不同的版本,并且有意使用旧版本(在LatestAndGreatest()发明之前),他仍然可以通过调用MyProject::Version1::BoringStableFunction()来实现。

请注意,客户端可以将其代码编写为MyProject::Version2::BoringStableFunction()。这样做的实质是客户端说:“我想要调用当前的#2版本,我希望实现保持不变--即使这个MyProject项目稍后会被更新。”

请注意,如何在不影响任何现有客户端的情况下执行其他开发:

代码语言:javascript
复制
namespace MyProject {
    namespace Version1 {
        void BoringStableFunction() {...}
    }
    inline namespace Version2 {
        void BoringStableFunction() {...}
        void LatestAndGreatest(int x) {...}
    }
    namespace Version3 {
        void BoringStableFunction() {...}
        void LatestAndGreatest(std::string x) {...}
    }   
}

当我准备向公众发布我的更改时,只需要做这个小小的编辑:

代码语言:javascript
复制
namespace MyProject {
    namespace Version1 {
        void BoringStableFunction() {...}
    }
    namespace Version2 {
        void BoringStableFunction() {...}
        void LatestAndGreatest(int x) {...}
    }
    inline namespace Version3 {
        void BoringStableFunction() {...}
        void LatestAndGreatest(std::string x) {...}
    }   
}

大多数客户一直在打电话给MyProject::BoringStableFunction()。他们的代码不需要编辑;在语法上仍然是有效的。但现在他们将突然利用我可能在BoringStableFunction()中更改的任何新实现。

如果他们如此大胆地使用我的MyProject::LatestAndGreatest(11),他们将需要被告知,他们现在需要更新他们的使用。因此,这表明,即使使用内联名称空间,仍然需要将思想纳入程序员与其客户端之间的契约中。

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

https://stackoverflow.com/questions/43420688

复制
相关文章

相似问题

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