我声明了两个模板,第一个将参数x
从类型T
转换为类型U
,第二个从类型U
转换为类型T
。如果我用10调用cast
,则编译器不会抱怨。我认为两者都符合要使用的要求,因此应该存在歧义,这是真的吗?这段代码显示10。
#include <iostream>
template<typename T, typename U>
U cast(T x) {
return static_cast<U>(x);
}
template<typename T, typename U>
T cast(U x) {
return static_cast<T>(x);
}
int main() {
std::cout << cast<int,float>(10) << '\n';
}
答案 0 :(得分:24)
使用cast<int, float>
时,将同时考虑两个模板。
template<typename T=int,typename U=float>
U cast(T x);
template<typename T=int,typename U=float>
T cast(U x);
然后我们替换:
template<typename T=int,typename U=float>
float cast(int x);
template<typename T=int,typename U=float>
int cast(float x);
目前,尚无可推论的类型。所以我们去解决重载问题。
在一种情况下,我们可以采用int
并在 calling 转换时转换为float
,在另一种情况下,我们可以采用int
并转换为int
进行呼叫投射时。请注意,我并没有考虑演员的 body ;身体与超载解决方案无关。
第二个非转换(在调用时)是更好的匹配,因此可以选择重载。
如果您这样做:
std::cout << cast<int>(10) << "\n";
事情变得更加有趣:
template<typename T=int,typename U=?>
U cast(T x);
template<typename T=int,typename U=?>
T cast(U x);
对于第一个,我们无法推论U
。对于第二个,我们可以。
template<typename T=int,typename U=?>
U cast(int x);
template<typename T=int,typename U=int>
int cast(int x);
因此,这里有一个可行的重载,并且被使用了。
答案 1 :(得分:2)
实例化不是模棱两可的,因为function参数与第一个模板参数完全匹配:文字0 <= i < needle.length
是10
,它也为第一个模板类型明确指定。
例如,当参数类型与显式指定的类型不匹配(因此,必须进行转换)时,可以使实例化不明确。
int