template metaprogramming

Pages: 12
Hello there,
I'm not an expert in any kind of compile time computing methods but i know that template metaprogramming provides such a functionality; I've seen the syntax and it's a bit different than common C++ syntax. But I also found a piece of code that does compile time computing just by using the constexpr keyword that was introduced in C++0x.
here it is :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
#include <iostream>

constexpr int factorial(int n)
{
    return n <= 1 ? 1 : (n * factorial(n-1));
}

template<int n> struct constN {
    constN() { std::cout << n << '\n'; }
};

int main() {
    std::cout << "4! = " ;
    constN<factorial(4)> out1; // computed at compile time
}


So, having this, do you think that there's any chance that these new capabilities ( probably increased in the future ) might replace template metaprogramming ?
Although template metaprogramming and compile-time calculations does overlap, main purpose of the templates is to make generic function/classes.

Template function can be executed at runtime and constexpr functions can be templated.
1
2
3
4
5
template<typename T>
constexpr T Pi()
{
    return static_cast<T>(3.14159265358979323846264338328L)
}

You should note that constexpr functions does not guarantee that their result would be known in compile time, when using templates you can force an error in this case.

So, template metaprogramming and constexpr entities would coexist.
Last edited on
@MiiNiPaa

constexpr functions does not guarantee that their result would be known in compile time

interesting, this wasn't mentioned where i read about them.

I guess i should learn more before i make such assumptions :)

Any way, thanks for this intelligible elucidation.
constexpr function works in compile time when all arguments are known in compile time. If compiler decided that something is not a compile time constant, function runs in runtime without any indication of it.

Also in C++11 constexpr function had draconic limitation. This and unability to have compiletime and runtime overloads means that you had to choose between compile time calculations or readability and runtime efficiency.
Sorry but i couldn't understand this part :

Also in C++11 constexpr function had draconic limitation. This and unability to have compiletime and runtime overloads means that you had to choose between compile time calculations or readability and runtime efficiency.

could you put it in simple words, please ? I'm a newbie !! :)

Edit : I don't mean that i don't understand the words, I just can't understand how I'm choosing between compile time calculations, readability and run time efficiency.
Last edited on
In C++11, constexpr functions could only contain a return statement. In C++14 this was changed to allow more constructs before returning.

constexpr is not part of a function's signature, so a function cannot be overloaded by it. It merely means that the compiler should enforce that the function is able to be run at compile time. It does not enforce that it will be run at compile.

EDIT:
Nezar wrote:
Edit : I don't mean that i don't understand the words, I just can't understand how I'm choosing between compile time calculations, readability and run time efficiency.
I can only guess, I will let MiiNiPaa answer this.
Last edited on
In C++11 you can only have one statement in your constexpr function: return statement. You could not use loops, local variables, branching and switches. You had to use recursion, ternary operators and functional programming style to get what you want. It was hard to read and often was not the most efficient way to do the job, so when function was called at runtime it wasn't performing as good as it could.
@LB

You mentioned in your blog that you're an expert in template metaprogramming. Now, given that C++14 allows more constructs before returning, do u think that this functionality can replace TMP some day ?
or will they just coexist as MiiNiPaa said ?

Edit : I'm talking about compile time calculations with templates, not generic code writing.
Last edited on
I don't think templates will ever "die".
constexpr's can't (and will not) do what templates can.
MiiNiPaa wrote:

You could not use loops, local variables,branching and switches

aha, now i get it !!
thanks.
@EssGeEich

I'm not saying that stuff like constexpr whould replace templates; I'm talking about they way templates are used for calculations at compile time which would probably be possible with new stuff introduced in the language. of course templates would never die.
@Nezar: The correct quoting comes with the quote tags as follows:
[ quote=username]Some text[/quote]

(Without the first space)
And it looks like...
username wrote:
Some text
@EssGeEich

Lol, i did it manually, it took me more than the time i spent on writing the paragraph it self !!
thanks for saving me :)
Nezar wrote:
You mentioned in your blog that you're an expert in template metaprogramming. Now, given that C++14 allows more constructs before returning, do u think that this functionality can replace TMP some day ?
or will they just coexist as MiiNiPaa said ?

Edit : I'm talking about compile time calculations with templates, not generic code writing
I don't have a blog and I am certainly no expert, but I do know quite a bit. (Hint: specialists and experts are not the same thing). JLBorges is quite knowledgeable and knows much more than I do. From where I stand I consider him to be an expert.

I think templates and constexpr functions will coexist for a long time. Neither works the way I would like, however - the first step to getting what I would like is adding static-if to the language. But then we will have three things that will coexist for a long time.
Last edited on
Things like generic functions, tag dispatch, SFINAE, etc. are impossible without templates. Also ability to easily ensure that something could be used only in compile time context is present only in templates. Also I would love to see type_traits without templates.
@LB: static ifs are kind of possible within template classes.
@LB:

Why not just template that??

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<bool>
void whatever()
{
    //do false
}

template<>
void whatever<true>()
{
    //do true...
}

Your code would then look like:

[code]//do whatever:
whatever<x == y>();


You could probably do even more if you experiment with variadic arguments.
Last edited on
Any stupid compiler will eliminate the check and the impossible block of an if statement if the truthness of the predicate can be determined at compile time, which will generally be the same cases where the predicate could be used as a template parameter. Static ifs are kind of worthless IMO.
@IWishIKnew:
Shouldn't it begin with template <bool> void whatever();?
Also, giving no body will give a compile-time error, which is the purpose of templates.
Sorry. I havn't practiced template specialization a whole lot.
Pages: 12