阅读和研究很多关于新的C ++ 11特性 - "内联命名空间"我不明白这个功能的真正好处是什么。
我可以很容易地拥有在"内联命名空间中定义的所有函数/类型"直接放在封闭的一个并具有相同的结果。 那么将函数/类型放在内联命名空间中的真正动机是什么? 分组功能/类型? 使用"内联命名空间"是否有任何与ADL相关的好处? 我认为ADL会表现得一样,因为有一个隐含的"使用"这个"内联命名空间的指令。"
EDIT1:
所以我认为以下是关键优势。 我们先说我们有这个:
namespace toplevel {
// Users can use toplevel::MyType
inline namespace current {
class MyType {};
} // inline namespace current
} // ns toplevel
现在,一些新的要求,我们需要一个新版本 可用但保持旧的完整:
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"命名空间 它是默认的。仍让用户访问"当前"但 with explicit :: current - 即这样:toplevel :: current :: MyType 顺便说一句 - 我的偏好甚至会重命名"当前" to"弃用"。
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
这听起来像是一个正确的场景吗?
答案 0 :(得分:3)
C++ 内联命名空间的主要动机确实涉及版本控制。除了问题中的最后一句话,您的理解是正确的:
<块引用>我的偏好甚至会将“当前”重命名为“已弃用”
使用内联命名空间的整个想法是命名空间名称不会改变——相反,这个特性允许命名空间名称不需要改变;现有名称可以永久存在,无需对代码进行大量更改。
相反,在发布版本时(当我们过去认为的“当前功能”现在变成“不推荐使用的功能”时),命名空间名称可以保持不变,但它们的默认状态会更新。
>让我们在代码中看到这一点:
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
项目稍后更新”>
请注意我如何在不影响任何现有客户的情况下执行额外的开发:
namespace MyProject {
namespace Version1 {
void BoringStableFunction() {...}
}
inline namespace Version2 {
void BoringStableFunction() {...}
void LatestAndGreatest(int x) {...}
}
namespace Version3 {
void BoringStableFunction() {...}
void LatestAndGreatest(std::string x) {...}
}
}
当我准备好向公众发布我的更改时,只需要进行这个微小的修改:
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)
,他们将需要被告知他们现在需要更新他们的使用情况。所以这表明,即使使用内联命名空间,仍然需要在程序员与其客户之间的合同中加入思想。