1

Question posed by josolanes:

I looked at your thread here: http://www.daniweb.com/forums/thread88255.html from a couple years back

And I'm starting to get a grasp of your first post. I understood how to do the factorial struct really quickly, but the _if and _for statements still make me feel uneasy, though I think I understand them. I think a bit more experience with it will help a lot with my confidence

One that I'd like help withis the following example of isPrime:

bool isPrime(int p, int i=2) 
{
    if (i==p)
        return 1; 
    if (p%i == 0)
        return 0;
    return isPrime (p, i+1);
}

I'd like to achieve this in a similar manner as the fibonacci one, with a single set of funcitons and templates (for each "case") if possible.

I've been thinking about it a bit, but my lack of experience with TMP seems to have me somewhat dumbfounded. I assume it's possible to do this in a single struct set, but can't quite figure it out since it has 2 variables, one as an input and the other changing.

I looked online for an isPrime TMP example and found one that uses a combination of about 3 struct sets to perform the above operation http://zwabel.wordpress.com/2008/12/18/c-template-support-in-kdevelop4-another-milestone/

I tried to modify it to work within a single struct set using conditional shorthand but can't quite figure it out

Is there a way to do the above in a single struct set? If so, how would you?

THe is_prime itself can be done with a single struct and a specialization for it:

template< int NUMBER, int DIVISOR = NUMBER - 1 > struct is_prime
{
    // compile-time assertion that NUMBER >= 2
    struct check { char check_it[ NUMBER - 1 ] ; } ;

    enum
    {
        // NUMBER is a prime number if
        result = (NUMBER % DIVISOR) && // it is not divisible by (NUMBER-1)
                // and not divisible by any number smaller than it
                 is_prime< NUMBER, DIVISOR-1 >::result
    } ;
};

template< int NUMBER > struct is_prime< NUMBER, 1 > // except 1
{
    enum { result = true } ;
};

Just to give you another example of a compile-time if and a compile-time for loop, I've added these:

// compile-time if- general case (ISPRIME is not true): print nothing
template< int NUMBER, bool ISPRIME > struct print_if_prime
{
    static inline void print() {}
};

// specialization: print the number if ISPRIME is true (it is a prime number)
template< int NUMBER > struct print_if_prime< NUMBER, true >
{
    static inline void print() { std::cout << NUMBER << '\n' ; }
};

// compile-time loop
// print all prime numbers in the range N to MAX inclusive
template< int N, int MAX > struct print_primes
{
    static inline void print()
    {
        // if N is a prime number, print it
        print_if_prime< N, is_prime<N>::result >::print() ;

        // print all prime numbers in the range N+1 to MAX inclusive
        print_primes< N+1, MAX >::print() ;
    }
};

// exit the loop with this specialization (we have already reached MAX)
template< int N > struct print_primes<N,N>
{
    static inline void print()
    {
        // if N is a prime number, print it
        print_if_prime< N, is_prime<N>::result >::print() ;
    }
};

And finally a main, to print all prime numbers upto 100

int main()
{
    print_primes<2,100>::print() ;
}

The code that you saw on the web is based on the metaprogram by Erwin Unruh, which issues error messages that would contain successive prime numbers. The original program by Unruh is given in the afternotes to this article: http://www.informit.com/articles/article.aspx?p=30667
You may find it worth your while to read the complete article from beginning to end.

2
Contributors
1
Reply
3
Views
7 Years
Discussion Span
Last Post by josolanes
0

Thanks vijayan121! I'm going to have to play with this a bit more today to really understand how to use it myself

I understand your example, now. But I had trouble trying to come up with it on my own

Thanks again! You've really helped me in understanding this a lot!

EDIT: reading the article now :)

Edited by josolanes: n/a

This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.