简体   繁体   English

重载解析如何与可变参数函数一起使用?

[英]How does overload resolution work with variadic functions?

Suppose I have this program: 假设我有这个程序:

#include <iostream>

int fun(...) {return 0;}

template <typename... Args>
int fun(const Args&...) {return 1;}

int fun(const double val) {return 2;}

int main()
{
  std::cout << fun(1,2,3) << fun(1) << fun(1.0);
  return 0;
}

This program returns the following: 该程序返回以下内容:

112

I understand why fun(1.0) would return 2 , as that's the closest matching function candidate, but why do the first 2 examples return 1 ? 我理解为什么fun(1.0)会返回2 ,因为那是最接近的匹配函数候选者,但为什么前2个例子返回1

This page ( http://en.cppreference.com/w/cpp/language/overload_resolution ) provides a reference of function overloading rules, but seems to stop short of covering variadics. 这个页面( http://en.cppreference.com/w/cpp/language/overload_resolution )提供了函数重载规则的参考,但似乎没有涵盖可变参数。 Where can I find out the rules for overloading of variadic / template variadic functions? 我在哪里可以找到可变参数/模板可变函数的重载规则?

why do the first 2 examples return 1 ? 为什么前两个例子返回1

A C-style variadic function is always the worst match (technically speaking it involves an "ellipsis conversion sequence" which is worse than any standard or user-defined conversion sequence). C风格的可变参数函数总是最差的匹配(从技术上讲,它涉及“省略号转换序列”,它比任何标准或用户定义的转换序列都要糟糕)。 For fun(1, 2, 3) , with the variadic function template, deduction is performed as usual giving Args = int , int , int . 为了fun(1, 2, 3) ,使用可变参数函数模板,可以照常执行演绎,给出Args = intintint This is an exact match. 这是完全匹配。

For fun(1) the variadic function template wins again because Args is deduced as int and once again we have an exact match, which is better than the floating-integral conversion required to call fun(double) . 为了fun(1) ,可变参数函数模板再次获胜,因为Args被推导为int并且我们再次具有完全匹配,这比调用fun(double)所需的浮点积分转换更好。

Where can I find out the rules for overloading of variadic / template variadic functions? 我在哪里可以找到可变参数/模板可变函数的重载规则?

The page you linked already covers what you need to know about C-style variadic functions: 您链接的页面已经涵盖了您需要了解的有关C风格可变参数函数的信息:

1) A standard conversion sequence is always better than a user-defined conversion sequence or an ellipsis conversion sequence. 1)标准转换序列总是优于用户定义的转换序列或省略号转换序列。

2) A user-defined conversion sequence is always better than an ellipsis conversion sequence 2)用户定义的转换序列总是优于省略号转换序列

For variadic templates there aren't really any special rules; 对于可变参数模板,实际上没有任何特殊规则; template parameter deduction is performed as usual and then the usual overload resolution rules are applied. 模板参数推导像往常一样执行,然后应用通常的重载决策规则。

The rules get more complicated in a case like this: 在这种情况下,规则变得更加复杂:

template <class... Args> int f(Args...) { return 1; }
template <class T> int f(T) { return 2; }
f(1); // returns 2

In this case the usual rules can't resolve the overload, but the second function is selected because it's "more specialized". 在这种情况下,通常的规则无法解决重载,但选择第二个函数是因为它“更专业”。 The rules for determining when one function template is more specialized than another are (in my opinion) very hard to understand. 确定一个功能模板何时比另一个更专业的规则(在我看来)很难理解。 You can find them at §14.5.6.2 [temp.func.order] in the C++11 standard. 您可以在C ++ 11标准的§14.5.6.2[temp.func.order]中找到它们。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM