【问题标题】:C++ When is it OK to extend the `std` namespace?C++ 什么时候可以扩展 `std` 命名空间?
【发布时间】:2017-04-25 01:01:47
【问题描述】:

SO 上的一个帖子说extending std is UB(好吧,当然,除非你是标准作家)。但时不时地,std 被愉快地扩展了。什么时候可以这样做?

【问题讨论】:

  • @NathanOliver 相关,但不是骗子。如果这是一个全新的问题,我会感到惊讶。但这绝对是个好东西。
  • 你绝对可以做的是为某些模板提供专业化,例如std::numeric_limits<my_own_number_type>
  • 您可以为 std 中期望的类型添加您的类型的专业化。
  • @Jarod42 我认为 来自std 的部分期待它 钉它。

标签: c++ c++11 namespaces std


【解决方案1】:

唯一可以将定义添加到std 命名空间的情况是对已存在于命名空间中的模板进行专门化并显式实例化模板。但是,仅当它们依赖于用户定义的类型时。

[namespace.std](标准草案):

  1. 如果 C++ 程序将声明或定义添加到命名空间 std 或命名空间 std 内的命名空间,则 C++ 程序的行为未定义,除非另有说明。只有当声明依赖于用户定义的类型并且特化满足原始模板的标准库要求并且没有明确禁止时,程序才能将任何标准库模板的模板特化添加到命名空间 std。

    李>
  2. 如果 C++ 程序声明,则其行为未定义

    (2.1) 标准库类模板的任何成员函数的显式特化,或

    (2.2) 标准库类或类模板的任何成员函数模板的显式特化,或

    (2.3) 标准库类或类模板的任何成员类模板的显式或部分特化。

    只有当声明依赖于用户定义类型的名称并且实例化符合标准库对原始模板的要求时,程序才能显式实例化标准库中定义的模板。


作为标准模板的一个示例,这些模板被明确设计为针对用户定义的类型进行扩展:std::hashstd::iterator_traits

【讨论】:

  • 谢谢,我正要向@Jarod42 询问“来自std 的那些期望它的人”的列表,但这已经足够了。
  • 我用 make_unique 函数扩展了 std 命名空间,用于 c++11,因为它是写成 here 的。这样可以吗?
  • @Walter 我用标准草案中的引号替换了 cppreference 引号。
  • @VictorPolevoy 不,向std 命名空间添加新功能是不行的。请参阅标准引用 [namespace.std]/1
  • 请注意,C++20 进一步限制了特化,特别是禁止函数模板使用它们。
【解决方案2】:

您可以为自定义数据类型设置模板特化。

例如:您自己的 std::hash 专用于 std::unordered_map

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-05-31
    • 1970-01-01
    • 1970-01-01
    • 2022-01-19
    • 2012-04-07
    • 1970-01-01
    • 2011-12-05
    • 2010-10-01
    相关资源
    最近更新 更多