Giter VIP home page Giter VIP logo

Comments (4)

pyb1993 avatar pyb1993 commented on August 19, 2024

我再阐述一下我的思路吧:

(1)为什么不存在递归呢?第16.4.1节不就是以print作为例子吗?一个递归版本,一个非递归版本。非递归版本用来终止递归.
(2)另外我的意思是,不需要那个非递归版本的print来终止递归,利用<if (!sizeof...(args)>就可以判断终止条件.我测试了一下,print(1,2,3,4)时它并不总是3,而是随着函数的递归调用变成了2,1.然后在第三次调用(既参数包为空)时编译器选定了非递归版本的print.
(3)我的问题在于将非递归版本的print注释掉就报错.我的代码如下:

#include <iostream>
using std::cout;
using std::endl;

//template<typename T>   //注释掉这个非递归版本的print
//void print(const T& t)
//{
//  cout << t;
//}

template<typename T, typename... args>
void print(const T &t, const args&... rest)
{
    auto m = sizeof...(args);//测试代码,m并不总是3.而是每次减1
    if (!sizeof...(args))//参数包为空
    {
        cout << t << endl;//没有分隔符
        return;
    }
    cout << t << ", ";
    print(rest...);/*这里不就是递归调用么?
    每一次调用就会将参数包的第一个参数绑定到 t 上面,而参数包的参数就少一个,3,2,1,
    最后一次就应该是0了,但是存在非递归版本的print时编译器会选择非递归版本的函数,
    如果没有非递归,那么递归版本也应该是可行函数啊?但是会报错*/
}

int main()
{
    print(1,2,3,4);
}

不知道我有没有说明白我的困惑?

from cppprimer.

pezy avatar pezy commented on August 19, 2024

@pyb1993 不好意思, 是我完全理解错了。

我基本上了解你的意图了, 但恐怕这是无法实现的。这里的递归, 和通常意义上的 runtime 递归是有区别的。原代码中的双函数递归, 是在编译期就确定的静态递归。

你试图将双函数简化成单函数, 但用的条件 if (!sizeof...(args)) 却是在编译期无法确定的,只有在 runtime 才可以确定其值(如你所言,每次减 1)。所以这一点和模版静态递归的本质冲突了, 故无法实现。


再说说你遇到的编译错误,编译时, 编译器碰到 print(rest...); 就会尝试去解开 rest 这个 pack. 而由于 if (!sizeof...(args)) 在编译期间无法确定其值,所以对于编译器而言,这个条件形同虚设。于是,解到最后, 发现最终的参数个数, 是 1. 而它找来找去, 也没看到参数个数为 1 的 print 声明。于是它困惑了,并抱怨在 IDE 里。

我也尝试了一下实现你的意图, 单函数递归来解这道题,却很遗憾的没有找到解决方案。。非常抱歉。

from cppprimer.

pyb1993 avatar pyb1993 commented on August 19, 2024

首先谢谢您的解答,我基本理解了.但是有一点不同意见 :
#[0]:我认为编译器不是在解到参数为1的时候报错的,而是在参数为0的时候报错的.```
##[1]因为我调用print(1)进行测试,发现是可以的,因为参数包rest是可以为空的.编译器编译的时候忽略了递归的终止条件(以前我忽略了模板静态递归的特点!),所以当参数只有1个(rest为空)的情况下它还会去调用print(rest...),然而这个时候一个参数都没有提供给print函数,这显然是不可以的.
###[2]这是我的理解,如有不对,请您指正.

from cppprimer.

pezy avatar pezy commented on August 19, 2024

@pyb1993 你说的是对的, 应该是参数个数为 0 的时候报错的。

from cppprimer.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.