Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ template recursion stop condition

Suppose I have the code:

template<size_t num> void actLoop(float* result, const float* rvector,
                                          size_t* xs, size_t indexIn=0)
{
    for(xs[num]=0; xs[num]<N; ++xs[num])
    {
        size_t index = indexIn+xs[num]*strides[num];
        if(num>0)
            actLoop<num-1>(result,rvector,xs,index);
        else
            result[index] = work(rvector,index,xs);
    }
}

It should create nested loop with nest level of num. When I try to compile it, I get compiler error about too deep recursion, i.e. seems compiler doesn't eliminate if(0>0) statement.

Is there a good way to make this happen, not having to create separate specialization for num=0?

like image 977
Ruslan Avatar asked Apr 26 '26 16:04

Ruslan


2 Answers

There's a way, Andrei Alexandrescu has presented it in one of his talks at Going Native 2013:

template<size_t num> void actLoop(float* result, const float* rvector,
                                          size_t* xs, size_t indexIn=0)
{
    for(xs[num]=0; xs[num]<N; ++xs[num])
    {
        size_t index = indexIn+xs[num]*strides[num];
        if(num>0)
            actLoop<(num > 0 ? num-1 : num)>(result,rvector,xs,index);
        else
            result[index] = work(rvector,index,xs);
    }
}

This refers to the same instantiation of actLoop if num is 0, therefore breaking the infinite instantiation.

like image 86
dyp Avatar answered Apr 28 '26 07:04

dyp


The if( num > 0 ) is a runtime condition. The recursion is happening at compile time. So no, there is no way to avoid the specialization for num = 0.

Why is it a problem though, to create the specialization for num = 0 ?

like image 28
thelamb Avatar answered Apr 28 '26 05:04

thelamb



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!