通过部分模板特化扩展命名空间标准

extending namespace std via partial template specialization

据我所知,我们可以(除了一些我不会在这里提及的例外)通过完全专门化 std 模板函数来 "extend" namespace std,例如std::swap,即

namespace std
{
    template<>
    void swap<Foo>(Foo& lhs, Foo& rhs){...}
}

完全有效。

从 C++11 开始,我们现在可以部分特化函数。我相信我们可以玩同样的游戏并通过部分专业化扩展 std,比如

namespace std
{
    template<typename T>
    void swap<Foo<T>>(Foo<T>& lhs, Foo<T>& rhs){...}
}

但是我对此不确定,并且在标准中找不到正确的解释部分。上面的代码是正确的还是会导致 UB?

PS:正如@Columbo 在回答中提到的,我们不能部分特化函数模板,即使在 C++11/14 中也是如此。出于某种原因,我认为可以做到这一点,我相信这至少是一个提案。

你的意思可能是 [namespace.std]/1:

A program may add a template specialization for any standard library template to namespace std only if the declaration depends on a user-defined type and the specialization meets the standard library requirements for the original template and is not explicitly prohibited181.


181) Any library code that instantiates other library templates must be prepared to work adequately with any user-supplied specialization that meets the minimum requirements of the Standard.

如果引入了函数模板的部分特化,此引用也将隐含地涵盖它们(因为它不限制自己对显式特化)。