看这段代码
template<class T>
void print(T var)
{
std::cout << var << " ";
}
template<class... Args>
void Variadic(Args... args)
{
print(args...);
}
int main()
{
Variadic();
}
当我编译它时说:
candidate: template void print(T)
candidate expects 1 argument, 0 provided
他是对的。事实上,我没有在参数包中提供任何参数。
但是为什么这段代码可以编译呢?
template<class T>
void print(T var)
{
std::cout << var << " ";
}
template<class... Args>
void Variadic(Args... args)
{
auto x = {0, (print(args), 0)...};
}
int main()
{
Variadic();
}
我做的第一件事是将第一个 0 插入 initializer_list<>
好的,现在让我们继续:编译器看到
(print(args), 0)...
它尝试调用 print()……哦等等……Parameter Pack 是空的,print() 函数有 1 个参数。
那么,为什么它的计算结果为 auto x = {0};
?
为什么编译器没有给我与以前完全相同的错误?
最佳答案
您误解了 ...
扩展运算符的工作原理。在您的示例中,当 args
是一个空包时,(print(args), 0)...
展开为空,而不是 print()
.
如果 args
以 x
的形式给出,它将扩展为 print(x), 0
。
如果 args
被指定为 x, y
它将扩展为 (print(x), 0), (print(y), 0)
.
等等
基本上,它扩展了所有包含 args
的表达式并将其应用于,而不仅仅是 args
位本身。
来自标准 [temp.variadic]:
- A pack expansion consists of a pattern and an ellipsis, the instantiation of which produces zero or more instantiations of the pattern in a list. The form of the pattern depends on the context in which the expansion occurs.
...
- The instantiation of a pack expansion that is neither a sizeof... expression nor a fold-expression produces a list E1, E2, ..., EN , where N is the number of elements in the pack expansion parameters. Each Ei is generated by instantiating the pattern and replacing each pack expansion parameter with its ith element.
关于c++ - 提供可变参数模板 : candidate expects 1 argument, 0(推导错误),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37996053/