Variadic模板:候选人期望1个参数,0提供(扣除错误)
Variadic template: candidate expects 1 argument, 0 provided (deduction error)
查看此代码段
template<class T>
void print(T var)
{
std::cout << var << " ";
}
template<class... Args>
void Variadic(Args... args)
{
print(args...);
}
int main()
{
Variadic();
}
当我编译时说:
候选人:模板void print(t)
候选人期望1个参数,0提供
他是对的。实际上,我没有在参数包中提供任何参数。
但是,为什么此代码编译?
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&lt;&gt;
好吧,现在让我们继续:编译器看到
(print(args), 0)...
它试图调用print()...哦,等等……参数pack 是空的,print()函数为1个参数。
为什么对auto x = {0};
进行评估?
为什么编译器不给我完全相同的错误?
您误解了...
扩展操作员的工作方式。在您的示例中,当args
是一个空包时,(print(args), 0)...
不扩展为note,而不是print()
。
如果给出args
为x
,它将扩展到print(x), 0
。
如果给出args
为x, y
,它将扩展到(print(x), 0), (print(y), 0)
。
等。
基本上它扩展了所有包含args
的表达式,并且应用于args
位本身。
来自标准[temp.variadic]:
- 包装扩展由图案和省略号组成 实例化产生零或更多的实例化 列表中的模式。模式的形式取决于 扩展发生。
...
- 包装扩展的实例化既不是尺寸...表达式也不是折叠表达产生列表e1,e2,...,...,en,, 其中n是包扩展参数中元素的数量。 每个EI都是通过实例化模式并替换每个EI生成的 包装参数及其ITH元素。
根据c 标准14.5.3/p4 variadic模板[temp.variadic] (重点是矿山):
包装扩展由图案和省略号组成, 实例化产生零或更多实例化 列表中的模式(如下所述)。模式的形式取决于 在发生扩展的情况下。
注意零或更多。在您的情况下,有一个空包,因此模式(print(args), 0)...
的实例为零。因此,您不会遇到编译时间错误,因为表达式:
auto x = {0, (print(args), 0)...};
实际评估:
auto x = {0};
也就是说,print
在编译器生成的代码中从未调用。
相关文章:
- 为什么在运行时没有向我们提供有关分段错误的更多信息?
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 错误:从"int"到"int*"的转换无效[-允许].我在下面提供了我的代码,我
- C++ VS 错误:<实验/文件系统>提供 std::experimental::文件系统的标头已被Microsoft弃用,将被删除
- 如何向用户显示特定错误,要求他/她使用循环再次提供输入?
- C++ Windows 凭据提供程序错误屏幕
- QScreen geometry()api为分辨率2736 x 1824和2560 x 1600提供了错误的值
- 错误:为函数__THROW__asm提供了初始化程序
- OpenGL 着色器程序无法验证,但不提供错误消息
- QT信号和插槽无法提供错误消息
- 为什么16位编译器会给未知的char []声明提供错误
- 为什么 size() 在与其他堆栈交换元素后提供错误的堆栈大小?
- 排序为最后一个位置的元素提供错误的输出
- 链接器为某些上下文中使用的集成静态常量成员提供错误"undefined symbol"
- scanf() 为最后一行输入提供错误的输出
- 尽管 QSqlQuery::exec 失败,但没有提供错误描述
- 如何保护CRTP不提供错误的超类
- 创建窗口不起作用,但不提供错误消息
- 程序以查找数字的阶乘并为负整数输入提供错误消息
- FindResource Api为DLL中的Text文件提供错误1813