可变参数模板未编译 [英] Variadic template not compiling

查看:41
本文介绍了可变参数模板未编译的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

#include 模板无效打印(A num,B ... args){std::cout <<数量<

编译时出现以下错误:

<前>在实例化 'void prints(A, B ...) [with A = int;B = {}]':错误:没有用于调用prints()"的匹配函数main.cpp:4:10: 注意:模板参数推导/替换失败:main.cpp:7:11: 注意:候选人需要至少 1 个参数,0 提供

解决方案

你的函数等待 1 个或多个参数:

template无效打印(A num,B ... args)

当你只用 1 个参数调用它时,args... 包是空的,所以递归调用:

prints(args...);

变成

prints();

但是您的函数等待(至少)1 个参数,因此无法匹配此调用.

您需要添加 prints() 的零参数重载以匹配空调用:

void prints(){ }

并且你必须在递归版本之前声明它.

正如从 C++17 开始的 Evg(感谢)所指出的,您可以避免零参数重载,并且使用 if constexpr,您只能在 args.. 时调用递归.. 不为空.

也就是说……从 C++17 开始你就可以写

template 无效打印(A num,B ... args){std::cout <<数量< 0u )打印(参数...);}

并且您不再需要零参数重载.

注意,如果你只是写(用简单的if,没有if constexpr)

 if ( sizeof...(args) > 0u )打印(参数...);

你得到(没有零参数重载)一个编译错误,因为当 sizeof...(args) 编译器必须编译 prints(args...) 部分 为零(正是 if constexpr 避免了这种情况).

#include <iostream>

template<typename A, typename... B>
void prints(A num, B... args){
    std::cout << num << std::endl;
    prints(args...);
}

int main(){
    prints(1,2,3);
    return 0;
}

When I compile, I get these errors:

In instantiation of 'void prints(A, B ...) [with A = int; B = {}]':
error: no matching function for call to 'prints()'

main.cpp:4:10: note:   template argument deduction/substitution failed:
main.cpp:7:11: note:   candidate expects at least 1 argument, 0 provided

解决方案

Your function waits for 1 or more parameters:

template<typename A, typename... B>
void prints(A num, B... args)

When you invoke it with only 1 parameter, the args... pack is empty, so the recursive call:

prints(args...);

becomes

prints();

But your function waits for (at least) 1 argument, so can't match this call.

You need to add a zero-argument overload of prints() to match the empty call:

void prints()
{ }

and you have to declare it before the recursive version.

As pointed by Evg (thanks) starting from C++17 you can avoid the zero-argument overload and, using if constexpr, you can call the recursion only when args... isn't empty.

That is... starting from C++17 you can write

template <typename A, typename... B>
void prints (A num, B... args) {
   std::cout << num << std::endl;

   if constexpr ( sizeof...(args) > 0u )
      prints(args...);
}

and you don't need the zero-argument overload anymore.

Observe that if you simply write (with a simple if, no if constexpr)

   if ( sizeof...(args) > 0u )
      prints(args...);

you get (without the zero-argument overload) a compilation error because the compiler has to compile the prints(args...) part also when sizeof...(args) is zero (it's exactly if constexpr that avoid this).

这篇关于可变参数模板未编译的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆