[英]Ambiguous call when recursively calling variadic template function overload
Consider this piece of code:考虑这段代码:
template<typename FirstArg>
void foo()
{
}
template<typename FirstArg, typename... RestOfArgs>
void foo()
{
foo<RestOfArgs...>();
}
int main()
{
foo<int, int, int>();
return 0;
}
It does not compile due to ambiguous call foo<RestOfArgs...>();
由于不明确的调用
foo<RestOfArgs...>();
它无法编译when RestOfArgs
has only one element ( {int}
).当
RestOfArgs
只有一个元素( {int}
)。
But this compiles without error:但这编译没有错误:
template<typename FirstArg>
void foo(FirstArg x)
{
}
template<typename FirstArg, typename... RestOfArgs>
void foo(FirstArg x, RestOfArgs... y)
{
foo(y...);
}
int main()
{
foo<int, int, int>(5, 6, 7);
return 0;
}
Why is there ambiguity in the first case?为什么第一种情况有歧义?
Why is there no ambiguity in the second case?为什么在第二种情况下没有歧义?
In Function template overloading在函数模板重载
There is lot of rules to tell which template function is more specialized (according to given parameters).有很多规则可以判断哪个模板函数更专业(根据给定的参数)。
The point which makes要点
template<typename> void foo();
template<typename, typename...> void foo();
ambiguous for foo<int>()
, but not foo<int>()
模棱两可,但不是
template<typename T> void foo(T);
template<typename T, typename... Ts> void foo(T, Ts...);
for foo(42)
is the following:对于
foo(42)
如下:
In case of a tie, if one function template has a trailing parameter pack and the other does not, the one with the omitted parameter is considered to be more specialized than the one with the empty parameter pack.
在平局的情况下,如果一个函数模板有一个尾随参数包而另一个没有,则具有省略参数的那个被认为比具有空参数包的那个更专业。
The answer by @ZangMingJie answers the difference in behavior your are observing in your code. @ZangMingJie 的回答回答了您在代码中观察到的行为差异。
I found it easier to understand the name resolution with the following change:我发现通过以下更改更容易理解名称解析:
template<typename FirstArg>
void foo()
{
printf("1\n");
}
template<typename FirstArg, typename SecondArg, typename... RestOfArgs>
void foo()
{
printf("2\n");
foo<SecondArg, RestOfArgs...>();
}
int main()
{
foo<int, int, int>();
return 0;
}
When there are two or more template parameters are used, the second function gets invoked.当使用两个或多个模板参数时,将调用第二个函数。 When there is one template parameters, the first function gets invoked.
当有一个模板参数时,第一个函数被调用。
Why is there ambiguity in the first case?为什么第一种情况有歧义?
RestOfArgs
can be empty. RestOfArgs
可以为空。
So foo<int>
can be instantiated as:所以
foo<int>
可以被实例化为:
template<int>
void foo()
{
}
and和
template<int,>
void foo()
{
foo<>();
}
both will compile, so it is ambiguous.两者都会编译,所以它是模棱两可的。
Actually foo<>()
won't compile, but it fails in the next instantiation, so it doesn't matter.实际上
foo<>()
不会编译,但是在下一次实例化时它会失败,所以没关系。
Why is there no ambiguity in the second case?为什么在第二种情况下没有歧义?
foo<int>(7)
can be instantiated as: foo<int>(7)
可以实例化为:
template<int>
void foo(int 7)
{
}
and和
template<int>
void foo(int 7)
{
foo();
}
but the second one is an error, because there are no foo taking no argument, so the only candidate is the first one, so there won't be ambiguous但是第二个是错误的,因为没有 foo 没有参数,所以唯一的候选人是第一个,所以不会有歧义
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.