C++何时可以扩展`std`命名空间?

8

一篇SO的帖子称扩展std是UB(当然,除非你是标准的编写者)。但是,std有时会被成功扩展。什么时候可以这样做呢?


related/dupe: https://dev59.com/YXRC5IYBdhLWcg3wXPwC - NathanOliver
@NathanOliver 相关,但不是重复的问题。不过,如果这是一个全新的问题,我会感到惊讶。但这绝对是一个好问题。 - Walter
你可以为某些模板提供特殊化,例如 std::numeric_limits<my_own_number_type> - Walter
2
你可以为那些需要特化的std类型添加你自己类型的特化。 - Jarod42
@Jarod42 我认为 来自std且期望它的那部分 很准确。 - green diod
2个回答

8
只有在模板已经存在于命名空间中,并且需要专门化模板或显式实例化模板时,才可以将定义添加到std命名空间中。但是,仅当它们依赖于用户定义的类型时才可以这样做。 [namespace.std](标准草案):
1. C++程序的行为未指定,如果它向命名空间std或命名空间内的命名空间添加声明或定义,除非另有规定。程序只能在声明依赖于用户定义的类型并且满足原始模板的标准库要求且未被明确禁止的情况下,向命名空间std添加任何标准库模板的专门化。 2. 如果声明以下内容,则C++程序的行为未指定: * 任何标准库类模板的任何成员函数的显式专门化; * 任何标准库类或类模板的任何成员函数模板的显式专门化; * 任何标准库类或类模板的任何成员类模板的显式或部分专门化。 程序只能显式实例化在标准库中定义的模板,前提是声明依赖于用户定义类型的名称并且实例化满足原始模板的标准库要求。
例如,专门为用户定义类型扩展的标准模板包括std::hashstd::iterator_traits

谢谢,我正准备向@Jarod42询问“期望它的std中的那些函数”的列表,但这已经足够好了。 - green diod
我在C++11中按照这里的写法,扩展了std命名空间的make_unique函数。这样做可以吗? - Victor Polevoy
@Walter 我用标准草案中的引号替换了cppreference中的引号。 - eerorika
@VictorPolevoy 不,向 std 命名空间添加新函数是不可以的。请参见标准引用 [namespace.std]/1。 - eerorika
请注意,C++20进一步限制了特化,特别是禁止函数模板的特化。 - Davis Herring

2

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

例如:为std::unordered_map添加您自己的std::hash特化实现。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接