![](/img/trans.png)
[英]Why am I getting “no matching function for call to '…'” with template function?
[英]When using function calls to template functions, I am faced with an unexpected matching template function for my call
对于以下代码,为什么编译器匹配我的 function 调用与(意外)模板 function:
首先是可用的 function 模板:
// First function template
template <typename T, typename U>
auto sub(T x, U y) {
return x - y;
}
// Second function template
template <typename T>
auto sub(T x, T y) {
return x - y;
}
现在假设我从一个模板参数推导语句开始:
sub(5.2, 2.1);
上面的语句应该反过来使用上面提供的第二个 function 模板实例化一个 function 实例(模板函数),最终看起来像这样:
template<>
double sub<double>(double x, double y) {
return x - y;
}
下一条语句不会实例化新模板 function,因为它将能够与之前创建的模板匹配。
sub<double>(2.3, 234.2);
现在下面的陈述是我有点困惑的地方。
sub<double>(2.3, 234.0f); // Weird one
尽管我提供了一个实际类型(double),但在模板参数中,我遇到了一个奇怪的结果。 我故意将第二个 function 参数设置为浮点数,以便与我们之前提到的 function 实例(模板函数)不完全匹配,并且预期会发生浮点提升并将浮点数提升为双精度值,然后匹配模板 function ,这不是最终发生的事情......而是它使用顶部提供的第一个 function 模板创建了一个新的 function 实例(模板函数),最终看起来像这样:
template<>
double sub<double, float>(double x, float y) {
return x - y;
}
我感到困惑的是,我如何认为编译器更喜欢促销而不是这样的东西,或者我可能把它与其他东西混淆了,我希望有人可以澄清一下。
也困扰我的一个问题是,我不知道如何才能显式调用我真正想要的模板 function,例如:
sub<double>(2, 2);
如果我希望它调用模板 function 并且两个参数类型都是double
并且只是希望我的 arguments 都从int
数字转换为double
怎么办。 按照这个逻辑,我不能这样做,因为编译器最终会创建一个新的 function 实例(模板函数),它看起来像这样:
template<>
double sub<double, int>(double x, int y) {
return x - y;
}
我必须提到我不是在谈论如何转换我的 arguments 因为我很清楚我可以在它们上使用static_cast
,我也不是在谈论做这样的事情:
sub<double, double>(2, 2);
As that would of course, use the first function template to create a new function instance (template function), not use the already available template function (which was created through the use of the second function template ). 如果真的有办法,有人可以解释我怎么能做到吗? 所有这一切,主要是因为我试图真正理解概念。
您可以提供模板参数的部分列表。 例如,如果您有
template <typename A, typename B, typename C>
void foo(A, B, C);
然后这些电话
foo(1,2,3);
foo<int>(1,2,3);
foo<int, double>(1,2,3);
foo<int, double, float>(1,2,3);
都很好。
所以sub<double>(2.3, 234.2f);
仍然匹配第一个 function 模板和第二个模板的实例化,前者更好匹配,因为它不需要转换。 只有当两个匹配都同样好时,重载决议才更喜欢非模板而不是模板1 。 如果模板更匹配,则使用它。
当两个参数的类型不同时,可以强制选择第二个模板:
auto x = (static_cast<float(*)(float, float)>(sub))(1, 2.0);
但这当然违背了目的。 为了方便使用,你需要引入一些其他的选择机制,例如
enum class same { type };
template <typename T, same = same::type>
auto sub(T x, T y)...
... sub<double, same::type>(2.3, 234.0f) ...
1或者更确切地说,需要推导模板参数的调用与不需要推导任何内容的调用。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.