zzz450001 2023-04-14 16:03 采纳率: 100%
浏览 15
已结题

关于递归解析参数包出错的疑问?

最近在学习参数包的使用,在使用递归进行参数包解析的时候,遇到了一个问题,不太明白,想要请教一下C++的大能:
先上代码:


//设置递归终点, 当参数包解包完全, 适配空包 Start
void ShowList()
{
    cout << endl;
}
//递归形式调用解包, 每一次解出一个参数
template<class T, class ...Args >
void ShowList(T& val, Args... args)
{
    static int num = 0;
    cout << "【" << ++num << "】:" << val << ",type:" << typeid(val).name() << endl;
    ShowList(args...);
    cout << "【" << num << "】:End" << endl;
    //if (sizeof...(args) == 0)
    //{
    //    ShowList();
    //}
}
// 参数包解析 End

int main()
{
    ShowList(1, 2, 3.4, "dsadsa", 2, 5, 6, "edsad", 4.8, 'q', 'w');
    return 0;
}

以上代码在编译的时候出现编译错误"error C2665: “ShowList”: 2 个重载中没有一个可以转换所有参数类型"。我测试过在函数ShowList()中的参数包只有当第一个参数为字符串的时候,后面无论什么类型都可以正常执行;但如果第一个参数是int、double、char这些基础类型常量的时候,都会出错。
后来我修改了一下代码:

int main()
{
    //ShowList(1, 2, 3.4, "dsadsa", 2, 5, 6, "edsad", 4.8, 'q', 'w');

    int n = 5;
    double d = 4.5;
    string str = "Hello";
    char c = 'c',
    ShowList(n/*d*//*c*/, 2, 3.4, "dsadsa", 2, 5, 6, "edsad", 4.8, 'q', 'w');

    return 0;
}

分别定一个变量存放int、double、char的数据,然后将其放在ShowList()函数的第一个参数,再编译执行都可以正常输出。
所以这是为什么呢?是因为直接使用常量,无法判断类型嘛?但看错误提示其实已经识别出这些常量的类型了,只是说没有与参数列表匹配的重载函数实例?

----------------------------------------------- 分割线 --------------------------------------------
最近人工智能流行,我就找了一个相关的人工智能帮查找上面的问题,可以给大家看看聊天记录:
代码还是上面的代码我就不截图了;

img

img

img

img

img

  • 写回答

2条回答 默认 最新

  • apples_kk 2023-04-14 16:34
    关注

    出现编译错误的原因是因为函数模板 ShowList 中的参数包使用了左值引用(T& val),但是在模板函数调用时传递了右值参数(比如字面量),这些右值是无法绑定到左值引用上的。为了解决这个问题,可以使用右值引用 T&& val 或者值传递T val,这样就可以绑定右值参数了,也就不会出现编译错误了。

    所以,更改模板函数如下:

    template<class T, class ...Args >
    void ShowList(T val, Args... args)
    {
        // ...
    }
    
    

    或者:

    template<class T, class ...Args >
    void ShowList(T&& val, Args&&... args)
    {
        // ...
    }
    
    

    这两种方式都能解决该编译错误。但是,需要注意的是,使用右值引用传递参数的形式会有一些细节需要处理,需要使用 std::forward 将右值转发给下一个函数(比如递归调用),确保引用的正确性。而使用值传递的形式则不需要这些额外的处理。

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

问题事件

  • 系统已结题 5月1日
  • 已采纳回答 4月23日
  • 创建了问题 4月14日

悬赏问题

  • ¥15 ansys fluent计算闪退
  • ¥15 有关wireshark抓包的问题
  • ¥15 需要写计算过程,不要写代码,求解答,数据都在图上
  • ¥15 向数据表用newid方式插入GUID问题
  • ¥15 multisim电路设计
  • ¥20 用keil,写代码解决两个问题,用库函数
  • ¥50 ID中开关量采样信号通道、以及程序流程的设计
  • ¥15 U-Mamba/nnunetv2固定随机数种子
  • ¥15 vba使用jmail发送邮件正文里面怎么加图片
  • ¥15 vb6.0如何向数据库中添加自动生成的字段数据。