[英]Overloading (not specializing) templates in std namespace
这是非常迂腐的但是在C ++ 03中,显然不符合程序在std
命名空间中重载 (非专门化 )模板函数:请参阅这里的提及以及对comp.lang.c ++的长期讨论。
即没关系:
namespace std
{
template <>
void swap (Foo & f, Foo & g)
{
// ...
}
}
但这不是(如果我理解正确的话......):
namespace std
{
template <typename T>
void swap (TempateFoo<T> & f, TempateFoo<T> & g)
{
// ...
}
}
这在C ++ 11中仍然如此吗? 此外,这是否也适用于模板类(如std::hash
),或仅适用于模板函数?
编辑:另外,有没有标准库实现的例子,后者会在实践中破坏? 如果没有,是否有一个特殊原因可以解除超载问题,就像上面的第二种情况一样? (什么可能在理论上破裂?)
在C ++中无法定义函数模板的部分特化,因此您的第二个示例定义了一个重载而不是一个特化。 由于标准只允许将特化添加到命名空间std
,因此您的重载是非法的。
这在C ++ 11中仍然如此吗?
是。
此外,这是否也适用于模板类(如std :: hash),或仅适用于模板函数?
无论如何,你不能重载类模板,你只能重载函数。 但是,相同的规则适用,如果特化取决于用户定义(意味着非标准)类型,则只能专门化类模板。
是否有一个特殊原因可以解除超载问题,就像上面第二种情况一样? (什么可能在理论上破裂?)
作为一个例子,实现可能想要获取函数的地址,但是如果你重载了函数,那么获取地址可能会导致歧义并且无法编译,这意味着你只是破坏了标准库中的有效代码。
n3376 17.6.4.2.1
如果C ++程序向命名空间std或命名空间std中的命名空间添加声明或定义,则它是未定义的,除非另有说明。 只有当声明取决于用户定义的类型并且特化符合原始模板的标准库要求且未明确禁止时,程序才可以将任何标准库模板的模板特化添加到命名空间std。
17.6.4.2.2
如果声明,C ++程序的行为是未定义的
- 标准库类模板的任何成员函数的显式特化,或
- 标准库类或类模板的任何成员函数模板的显式特化,或
- 标准库类或类模板的任何成员类模板的显式或部分特化。
仅当声明取决于用户定义类型的名称并且实例化符合原始模板的标准库要求时,程序才可以显式实例化标准库中定义的模板。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.