简体   繁体   中英

MetaProgramming in c++

I am new to c++ and need help with metaprogramming. I have checked out the enum example wherein the call factorial<4>::value yields 24 .

What I need is a modification to the code so that factorial<4>() returns 24 . Have been trying it for quite some time now and do not know how to exactly search for it on the internet too. Any help would be much appreciated. Thank you !

Here is what I have at the moment:

template <int N>
struct factorial
{
    enum { value = N * factorial<N - 1>() };
};

template <>
struct factorial<0>
{
    enum { value = 1 };
};

You can use a constexpr function:

template<int N>
constexpr int factorial() {
    return N * factorial<N - 1>();
}

template<>
constexpr int factorial<0>() {
    return 1;
}

Live demo

This will allow you to call:

factorial<4>();

and get 24 as a returned value.


Alternatively you can use the implicit conversion operator operator int() to perform an implicit conversion, of the struct to int :

template<int N>
struct factorial {
    static const int value = N * factorial<N-1>::value;
    operator int() { return value; }
};

template<>
struct factorial<0> {
    static const int value = 1;
    operator int() { return value; }
};

Live demo

To just use the function call like a function call, you need to use constexpr (a new addition to C++11). Note that when you do use this, you do not need to use a template at all though. Though there are some limitations, the basic syntax is that of a normal function:

int constexpr fact(int x) { return x == 0 ? 1 : x * fact(x - 1); }

This is still computed at compile time though. For example, if you wanted to use it to specify the size of an array, you could do so:

int main(){
    int array[fact(5)];
}

Likewise, you can use such a result as a case in a switch statement:

#include <iostream>
#include <cstdlib>

int constexpr fact(int x) { return x == 0 ? 1 : x * fact(x - 1); }

int main(int agc, char **argv){
    switch (std::atoi(argv[1])) {
    case fact(1) :
    case fact(2):
    case fact(3):
    case fact(4):
    case fact(5):
        std::cout << "You entered a perfect factorial";
        break;
    default:
        std::cout << "I'm not sure about that";
    }
}

[compiled/tested with gcc 4.8.1]

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM