C++11 内联命名空间与直接在封闭命名空间中嵌入类型
C++11 inline namespace vs embedding the types directly in the enclosing namespace
阅读和研究大量有关新的 C++11 功能 - "内联命名空间"的信息 我不明白这个功能的真正好处是什么。
我可以轻松地将"内联命名空间"中定义的所有函数/类型直接放置在封闭的命名空间中并具有相同的结果。 那么将函数/类型放在内联命名空间中的真正动机是什么? 对功能/类型进行分组? 使用"内联命名空间"是否有任何与 ADL 相关的好处? 我认为 ADL 的行为与这个"内联命名空间"有一个隐式的"using"指令相同。
编辑1:
所以我认为以下几个是关键优势。 假设最初我们有这个:
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
最后这样做。内联移动到"下一个"命名空间制作 它是默认值。仍然允许用户访问"当前",但 使用显式 ::当前 - 即这样:顶级::当前::MyType 顺便说一句 - 我的偏好甚至会将"当前"重命名为"已弃用"。
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
这听起来像是一个正确的场景吗?
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)
,则需要通知他们现在需要更新他们的用法。 因此,这表明,即使使用内联命名空间,仍然需要将思想放入程序员和他的客户之间的契约中。
- 从父命名空间重载类型
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- 如何对命名空间限定类型进行类型定义?
- Boost.Python :C++模板类型匹配的嵌套命名空间
- 如何为缺少预定义运算符而不扩展命名空间"std"的标准类型定义运算符>> (istream &, ...)?
- 如何理解c++中在命名空间内部定义的枚举类型enum
- 为什么找不到使用命名空间中定义的类型实例化的 std::weak_ptr 的重载运算符==?
- C++ ,错误:命名空间'std'中的'shared_ptr'未命名模板类型
- 错误:命名空间"std"中没有名为"invoke_result_t"的类型 GCC-7
- 命名空间中的'bad_cast' 'std' 未命名类型错误
- 使用用作类型 C++ 的命名空间
- 命名空间'std'中的'vector'没有模板类型
- C++11 内联命名空间与直接在封闭命名空间中嵌入类型
- 为什么类型特征不适用于命名空间范围内的类型?
- 如何使函数模板仅适用于特定命名空间中的类型
- 在全局命名空间中重载不依赖于用户定义类型的标准定义类型的运算符是否格式正确?
- 在C 中重新解析命名空间内的全局类型
- 位置实用程序例程与使用类型相同的命名空间
- MISRA C++规则 14-5-1:在与类型关联的命名空间中声明的泛型函数模板的名称
- 基于命名空间类型和primitif类型的成员函数重载