指针与const指针的部分排序

时间:2019-02-18 20:01:58

标签: c++ templates

由于功能模板的部分排序,以下内容似乎是明确的:

template <class T> void f(T*) {
   cout << "T*" << endl;
}

template <class T> void f(const T*) {
   cout << "const T*" << endl;
}

int main(){
    int *p = nullptr;
    f(p);
}
在两种情况下,

T都推导为int,并且两个专业都可行,第二个要求从int *const int*的隐式资格转换。两者都被添加到过载集中。

为了找到最佳可行的功能,我们转向部分排序。我们为每种类型合成新的类型,并获得void f(X*)void f(const Y*)。然后我们在两者之间进行类型推导。 [temp.deduct.partial]¶8:

  

使用所得类型P和A,然后按17.8.2.5中所述进行推导。 (...)如果给定类型的推导成功,则认为自变量模板中的类型至少与自参数模板中的类型一样专业。

在给定template <class T> void f(T*)的情况下,const Y*的扣除是否成功?是的,使用T=const Y

在给定template <class T> void f(const T*)的情况下,X*的扣除是否成功?是的,使用T=X(需要隐式资格转换)。

因此,X和Y至少彼此一样专门化,这意味着两个专门化都至少与另一个同样专门化,这意味着调用是不明确的。

除了不是,所以我在上面哪里出错了?

2 个答案:

答案 0 :(得分:1)

我找出了哪里出了问题:

  

为了找到最佳可行的功能,我们转向部分排序。

不,我们没有。为了找到最佳可行的功能,我们按顺序进行[over.match.best]中的步骤。部分排序只是该列表上的一个点,实际上我们从来没有得到过,因为最佳的可行函数是在列表的上一步找到的(对于某些参数j,,ICSj(F1)比ICSj(F2))。

这两个专业确实确实是同等专业的,但这并不重要,因为我们从不首先使用偏序。

答案 1 :(得分:0)

template <class T> void f(const T*)确实比template <class T> void f(T*)更专业,但后者是完全匹配。

如果您查看overload_resolution#best_viable_function

  

最佳可行功能:

     

1)F1至少有一个参数,其隐式转换要好于F2的相应隐式转换。
  [..]
  5),或者如果不是这样,则F1和F2都是模板专业化,而F1根据模板专业化的部分排序规则更专业化