我已经注意到很多关于模板的问题,这些问题是由于部分排序规则造成的,而且它们似乎彼此不一致.我以为我会自己深入了解标准并将其排除在外.忍受我.
gcc和clang似乎都同意用于确定模板排序的算法,但该算法实际上并未出现在标准中.没有特别的顺序:
template <typename T> void foo(T, T); // (1)
template <typename T, typename U> void foo(T, U); // (2)
Run Code Online (Sandbox Code Playgroud)
temp.deduct.type/2清楚地表明Ps必须有一组推导出的值.但是在偏序规则中没有这样的陈述.所描述的算法仅进行成对P/A匹配,因此从(2)到(1)via的合成调用foo(U{}, V{})可以成功推导.gcc和clang都认为(1)更专业.
template <typename T>
struct identity { using type = T; };
template<typename T> void bar(T, T ); // (1)
template<typename T> void bar(T, typename identity<T>::type ); // (2)
Run Code Online (Sandbox Code Playgroud)
这里,如果为(2)Unique2和()合成typename identity<Unique2>::type == Unique2,那么类型推导将在两个方向上成功并且调用bar(0,0)将是模糊的.然而,似乎是两种编译器,而不是简单地把typename identity<Unique2>::type作为Unique2_b,从而由式(2)(1)失败(基于隐含缺少一致性规则)制作模板扣除.
与前面的示例相同,但现在定义:
template <typename T> struct identity; template <> struct identity<int> …Run Code Online (Sandbox Code Playgroud)