撇开是否应该从std
命名空间中专门化一个函数模板的策略和语义问题,
以下代码段不起作用:
class stackiterator {};
struct stack { stackiterator Begin() { return stackiterator{};} };
#include <iterator>
namespace std
{
template <> stackiterator begin<stack>(stack& S)
{
return S.Begin();
}
}
但是,以下代码段可以正常工作:
class stackiterator {};
struct stack { stackiterator begin() { return stackiterator{};} };
#include <iterator>
namespace std
{
template <> stackiterator begin<stack>(stack& S)
{
return S.begin();
}
}
关键区别在于Begin()
vsbegin()
作为 的成员函数的存在stack
。std::begin()
定义为:
template <class C> auto begin(C& c) -> decltype(c.begin());
template <class C> auto begin(const C& c) -> decltype(c.begin());
当您专门化一个函数模板时,您仍然必须保持返回类型相同。当您没有begin()
作为 的成员时Stack
,编译器不知道如何确定返回类型。
这就是编译器产生错误的原因。
顺便说一句,还有另一个 SO 帖子部分回答了什么可以专门化,什么不能专门化。
查看标准中处理的部分std::begin()
,第 24.3 节,我看不到任何关于无法专业化的内容std::begin()
。