Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c++ support for last call optimization in template metaprogramming

Tags:

c++

I am reading about C++ templates and would like to contrast two different implementations of a function which computes sum from 0 to N.

Unfortunately, I have problems and would like to address a few questions through examples:

Code for naive sum:

#include <stdio.h>

template<int N>
struct Sum {
    // Copied the implementation idea from Scott Meyers book
    // "Effective C++". Is there a better way?
    enum { value = N + Sum<N - 1>::value };
};

template<>
struct Sum<0> {
    enum { value = 0 };
};

int main() {
    // Works well in this case, but gives compilation error, if
    // it's called with a larger value, such as 10000
    // (error: template instantiation depth exceeds maximum of 900").
    // How to improve the program properly, that it would
    // not give compile time error?
    printf("%d\n", Sum<100>::value);
}

Now my idea for an improvement is to use an accumulator:

template<int Acc, int N>
struct Sum {
    enum { value = Sum<Acc + N, N - 1>::value };
};

// Is that an appropriate way of writing the base case?
template<int Acc> 
struct Sum<Acc, 0> {
    enum { value = Acc };
};

However, when compiled with simple g++ on Ubuntu OS:

int main() {
    // Still gives the "depth exceeded" error.
    printf("%d\n", Sum<0, 1000>::value);
}

Hence, my main concern is:

Does any modern c++ compiler support last call optimisation for template metaprogramming? If yes, what is an appropriate way to write code for such optimisation?

like image 821
mercury0114 Avatar asked Nov 10 '22 00:11

mercury0114


1 Answers

Does any modern c++ compiler support last call optimisation for template metaprogramming? If yes, what is an appropriate way to write code for such optimisation?

No, and it wouldn't make sense. Template instantiations are not function calls... last/tail call optimisation has no relevance here. Unlike function calls, template instantiations are not transient with automatic variables to reclaim; rather, each template instantiation becomes a new type in the compiler's state.

like image 182
Tony Delroy Avatar answered Nov 15 '22 06:11

Tony Delroy