为什么对模板的调用不模棱两可?
Why isn't this call to a template ambiguous?
我声明了两个模板,第一个将参数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';
}
当您使用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);
此时,没有要推断的类型。 所以我们去重载解决。
在一种情况下,我们可以在调用cast 时采用int
并转换为float
,而在另一种情况下,我们可以采用int
并在调用cast 时转换为int
。 注意,我根本不在看演员的身体;主体与过载分辨率无关。
第二个非转换(在调用点(是更好的匹配,因此选择重载。
如果您这样做:
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);
所以这里我们有一个可行的重载,它被使用。
实例化不是模棱两可的,因为函数参数与第一个模板参数完全匹配:文字10
是一个int
,它也为第一个模板类型显式指定。
当参数类型与显式指定的类型不匹配时,可以使实例化变得不明确(因此,需要进行转换(,例如
// error: call of overloaded 'cast<int, float>(unsigned int)' is ambiguous
std::cout << cast<int,float>(10u) << "n";
相关文章:
- 调用重载的"<大括号括起来的初始值设定项列表>"对于对来说就足够了是模棱两可的
- 为什么对模板的调用不模棱两可?
- 模棱两可的调用 - 模板化函数
- C++ lambda 模棱两可的调用
- C++11 中对超载'ref(Select::Expressions::Code&)'的调用模棱两可
- 是可调用和模棱两可的调用:g++ 或 clang 中的错误
- 超载的调用是模棱两可的
- C 从同一基本模板类覆盖功能,具有多个继承模棱两可的函数调用
- MSVC发现这种方法调用模棱两可,而Clang / GCC则不然吗?
- 为模棱两可的超载功能调用创建默认值
- 重载函数的调用 - 以继承的类作为参数 - 是模棱两可的
- 为什么对函数的调用"sample_mean"模棱两可的?
- 对 glm::slerp 的模棱两可的调用
- 超载的调用是模棱两可的
- 对重载函数的模棱两可的调用,即使一个更专业
- 为什么 main() 中的调用 'A a(c);' 不模棱两可?
- Gtkmm,重载的'Scale()'的调用是模棱两可的
- 调用重载<大括号括起来的初始值设定项列表>是模棱两可的,如何处理?
- 调用超载to_string模棱两可
- 对函数的调用在C++中是模棱两可的.候选函数是原型和函数本身