[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

comp.lang.c++

template metaprogramming syntax

nooneinparticular314159@yahoo.com

10/1/2008 4:12:00 AM

I'm trying to understand template metaprogramming syntax. It's been
years since I've touched C++, so this may actually be a C++ syntax
issue (although it seems that the language has changed somewhat.)

The following example comes from http://www.codeproject.com/KB/cpp/crc...

template< int i >
class FACTOR{
public:
enum {RESULT = i * FACTOR<I-1>::RESULT};
};

class FACTOR< 1 >{
public:
enum {RESULT = 1};
};

In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
purpose of the ::RESULT? As I understand it, this should be calling a
method called RESULT, but I don't think this is what is actually
happening.

Also, why is everything done on one line with enumerated types in
every template example I see? Why are enumerated types used instead
of normal loops? Is this because the loops must be evaluated as
constants at compile time?

Thanks!
4 Answers

sonison.james

10/1/2008 9:03:00 AM

0

On Oct 1, 12:12 pm, "nooneinparticular314...@yahoo.com"
<nooneinparticular314...@yahoo.com> wrote:
> I'm trying to understand template metaprogramming syntax.  It's been

> In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
> purpose of the ::RESULT?  As I understand it, this should be calling a
> method called RESULT, but I don't think this is what is actually
> happening.

There are some typos in the code provided. Here's the same code with a
sample usage which would probably make the intention clear

#include <iostream>
using namespace std;

template< int i >
class FACTOR{
public:
enum {RESULT = i * FACTOR<i-1>::RESULT};

};

template<>
class FACTOR< 1 >{
public:
enum {RESULT = 1};

};

int main()
{
cout << "3!=" << FACTOR< 3 >::RESULT << endl;
}

In this sample we can let the compiler evaluate for us the value of a
factorial of a number at compile time. Since at compile time the
compiler does not have access to run time entities like objects or
invoke a function calls meta programming is in some sense restricted
to manipulate only entities available at compile time like types
including enums.

In case you haven't already checked out boost MPL, it has some good
reads at http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/...

Thanks and regards
Sonison James

Maxim Yegorushkin

10/1/2008 10:23:00 AM

0

On Oct 1, 5:12 am, "nooneinparticular314...@yahoo.com"
<nooneinparticular314...@yahoo.com> wrote:
> I'm trying to understand template metaprogramming syntax.  It's been
> years since I've touched C++, so this may actually be a C++ syntax
> issue (although it seems that the language has changed somewhat.)

The syntax did not change.

> The following example comes fromhttp://www.codeproject.com/KB/cpp/crc...
>
> template< int i >
> class FACTOR{
>   public:
>       enum {RESULT = i * FACTOR<I-1>::RESULT};
>
> };
>
> class FACTOR< 1 >{

this should be:

template<> class FACTOR< 1 >

>   public:
>       enum {RESULT = 1};
>
> };
>
> In the line enum {RESULT = i * FACTOR<I-1>::RESULT};, what is the
> purpose of the ::RESULT?

:: is the scope resolution operator. FACTOR<I-1>::RESULT says lookup
member RESULT in FACTOR<I-1>.

> As I understand it, this should be calling a
> method called RESULT, but I don't think this is what is actually
> happening.

Everything here happens in compile time, so that no call can be made.
As RESULT member is essentially an integer whose value is known at
compile time FACTOR<I-1>::RESULT yields an integer.

> Also, why is everything done on one line with enumerated types in
> every template example I see?

It can be static constant integers as well, however, some old
compilers could not handle it. Enums is a bit more portable. I.e. in
this context:

enum {RESULT = 1};

is the same as:

static int const RESULT = 1;

> Why are enumerated types used instead of normal loops?  
> Is this because the loops must be evaluated as
> constants at compile time?

Compile time loops can only be expressed as recursion, because you can
not change variables at compile time.

The following may help you get started with template metaprogramming:
http://www.boost.org/doc/libs/1_36_0/libs/mpl/doc/tutorial/reso...

--
Max



nooneinparticular314159@yahoo.com

10/1/2008 7:37:00 PM

0

Thanks! So to see if I understand this correctly, the line:
enum {RESULT = i * FACTOR<I-1>::RESULT};

means that I am going to perform a computation where I multiply the
result of evaluating the class FACTOR on the value I-1, and I'm going
to store that result in RESULT, which the compiler stores somewhere as
a constant. Then with the RESULT after the ::, I'm directing the
compiler to look up the value contained in RESULT, and that is the
value that is actually being returned from the evaluation of the
entire line. Is that correct?

Thanks!

Hendrik Schober

10/1/2008 9:56:00 PM

0

nooneinparticular314159@yahoo.com wrote:
> Thanks! So to see if I understand this correctly, the line:
> enum {RESULT = i * FACTOR<I-1>::RESULT};
>
> means that I am going to perform a computation where I multiply the
> result of evaluating the class FACTOR on the value I-1, and I'm going
> to store that result in RESULT, which the compiler stores somewhere as
> a constant. Then with the RESULT after the ::, I'm directing the
> compiler to look up the value contained in RESULT, and that is the
> value that is actually being returned from the evaluation of the
> entire line. Is that correct?

AFAIU, no.
I have added some parentheses:
enum { RESULT = i * (FACTOR<I-1>::RESULT) };
The 'FACTOR<I-1>::RESULT' is a compile-time constant
of (I-1)! which is used to calculate the compile-time
constant 'RESULT'.
Does this help?

> Thanks!

Schobi